问题描述
我有一张像
姓名 | 总计 | 日期 |
---|---|---|
A | 10 | 2020-12-01 |
B | 5 | 2020-12-01 |
A | 10 | 2020-12-02 |
B | 15 | 2020-12-02 |
现在我有一个姓名列表和日期列表
@NameList = '[A],[B],[C],[D]'
@DateList = '[2020-12-01],[2020-12-02],[2020-12-03],[2020-12-04]'
如何查询以获取 @NameList
和 @DateList
中可用的每个名称和日期的数据?
预期结果
姓名 | 总计 | 日期 |
---|---|---|
A | 10 | 2020-12-01 |
B | 5 | 2020-12-01 |
C | 0 | 2020-12-01 |
D | 0 | 2020-12-01 |
A | 10 | 2020-12-02 |
B | 15 | 2020-12-02 |
c | 0 | 2020-12-02 |
D | 0 | 2020-12-02 |
A | 0 | 2020-12-03 |
B | 0 | 2020-12-03 |
c | 0 | 2020-12-03 |
D | 0 | 2020-12-03 |
A | 0 | 2020-12-04 |
B | 0 | 2020-12-04 |
c | 0 | 2020-12-04 |
D | 0 | 2020-12-04 |
解决方法
JSON 方法怎么样?
假设名称和日期从不包含双引号,您可以使用字符串函数将它们转换为 JSON 字符串,并使用 openjson()
将每个列表取消嵌套为行。最后一步是将原始表带上 left join
。
declare @NameList nvarchar(max) = '[A],[B],[C],[D]';
declare @DateList nvarchar(max) = '[2020-12-01],[2020-12-02],[2020-12-03],[2020-12-04]';
select n.name,coalesce(t.total,0) as total,d.dt
from openjson('[' + replace(replace(@NameList,'[','"'),']','"') + ']')
with(name nvarchar(max) '$') n
cross join openjson('[' + replace(replace(@DateList,'"') + ']')
with(dt date '$') d
left join mytable t on t.name = n.name and t.date = d.dt
,
您可以使用 string_split()
拆分列表,然后使用 left join
引入现有数据:
declare @NameList nvarchar(max) = '[A],[2020-12-04]';
select v.name,v.date,0) as total
from string_split(@namelist,',') n cross join
string_split(@datelist,') d cross apply
(values (replace(replace(n.value,''),convert(date,replace(replace(d.value,''))
)
) v(name,date) left join
yourtable t
on t.name = v.name and t.date = v.date
这里唯一真正的技巧是使用 apply
删除方括号。
Here 是一个数据库小提琴。
,使用这个
select t1.name,t2.[date] from
[table] t1
cross apply [table] t2