标记列中不具有指定组合的项目
Flag items not having the specified combination in a column
我需要标记没有指定 DC 和存储位置组合的 ID#。例如:
每个 DC 的文章必须具有以下组合:
直流电
存储位置
DC01
ABC、BCA、DCA
DC02
ABC、BCA
DC03
ABC、DCA
我想要的结果如下所示,因为我想显示缺少的存储位置。
ID#
DC#
存储位置
旗帜
1
DC02
ABC
好
1
DC02
商业银行
好
2
DC01
ABC
不好
2
DC01
商业银行
不好
错误条目是因为缺少 'DCA' 条目。到目前为止,我有以下内容,但我无法弄清楚如何计算每个 ID 的匹配数(即 DC01 必须为 3,以便标志为 Good else Bad)。一旦标志被弄清楚,我唯一能想到的就是做一个联合(每个组合一个 select 语句) - 有没有更优化的方法来做到这一点?
select
ID,
DC,
Storage_Location
FROM table
where
DC = 'DC01' AND Storage_location in ('ABC', 'BCA', 'DCA')
group by ID, DC, Storage_location
table包含多个ID,每个ID有不同的组合:
ID#
DC#
存储位置
1
DC02
ABC
1
DC02
商业银行
2
DC01
ABC
2
DC01
商业银行
3
DC03
ABC
3
DC03
DCA
使用 returns 所有 DC
和他们想要的 StorageLocation
的 CTE,并加入 table。
还聚合在 table 中并使用 STRING_AGG()
(需要 2017 版本的 SQL 服务器)为每个 DC
收集他们在逗号分隔列表中的实际 StorageLocation
并加入此查询:
WITH cte(DC, StorageLocation) AS (
SELECT 'DC01', 'ABC,BCA,DCA' UNION ALL
SELECT 'DC02', 'ABC,BCA' UNION ALL
SELECT 'DC03', 'ABC,DCA'
)
SELECT t.*, CASE WHEN s.DC IS NULL THEN 'Bad' ELSE 'Good' END Flag
FROM tablename t INNER JOIN cte c
ON c.DC = t.DC
LEFT JOIN (
SELECT DC, STRING_AGG(StorageLocation, ',') WITHIN GROUP (ORDER BY StorageLocation) StorageLocation
FROM tablename
GROUP BY DC
) s ON s.DC = c.DC AND s.StorageLocation = c.StorageLocation
ORDER BY t.ID, t.DC, t.StorageLocation;
参见demo。
您可以使用STRING_AGG
查看数据是否完整。例如:
select
id, dc, location,
case when
(
select t.dc + ':' + string_agg(t2.location, ',') within group (order by t2.location)
from mytable t2
where t2.id = t.id and t2.dc = t.dc
) in ('DC01:ABC,BCA,DCA', 'DC02:ABC,BCA', 'DC03:ABC,DCA') then
'GOOD'
else
'BAD'
end as status
from mytable t
order by id, dc, location;
子查询是必要的,因为在 SQL 服务器中还没有 STRING_AGG
的分析版本。
我需要标记没有指定 DC 和存储位置组合的 ID#。例如:
每个 DC 的文章必须具有以下组合:
直流电 | 存储位置 |
---|---|
DC01 | ABC、BCA、DCA |
DC02 | ABC、BCA |
DC03 | ABC、DCA |
我想要的结果如下所示,因为我想显示缺少的存储位置。
ID# | DC# | 存储位置 | 旗帜 |
---|---|---|---|
1 | DC02 | ABC | 好 |
1 | DC02 | 商业银行 | 好 |
2 | DC01 | ABC | 不好 |
2 | DC01 | 商业银行 | 不好 |
错误条目是因为缺少 'DCA' 条目。到目前为止,我有以下内容,但我无法弄清楚如何计算每个 ID 的匹配数(即 DC01 必须为 3,以便标志为 Good else Bad)。一旦标志被弄清楚,我唯一能想到的就是做一个联合(每个组合一个 select 语句) - 有没有更优化的方法来做到这一点?
select
ID,
DC,
Storage_Location
FROM table
where
DC = 'DC01' AND Storage_location in ('ABC', 'BCA', 'DCA')
group by ID, DC, Storage_location
table包含多个ID,每个ID有不同的组合:
ID# | DC# | 存储位置 |
---|---|---|
1 | DC02 | ABC |
1 | DC02 | 商业银行 |
2 | DC01 | ABC |
2 | DC01 | 商业银行 |
3 | DC03 | ABC |
3 | DC03 | DCA |
使用 returns 所有 DC
和他们想要的 StorageLocation
的 CTE,并加入 table。
还聚合在 table 中并使用 STRING_AGG()
(需要 2017 版本的 SQL 服务器)为每个 DC
收集他们在逗号分隔列表中的实际 StorageLocation
并加入此查询:
WITH cte(DC, StorageLocation) AS (
SELECT 'DC01', 'ABC,BCA,DCA' UNION ALL
SELECT 'DC02', 'ABC,BCA' UNION ALL
SELECT 'DC03', 'ABC,DCA'
)
SELECT t.*, CASE WHEN s.DC IS NULL THEN 'Bad' ELSE 'Good' END Flag
FROM tablename t INNER JOIN cte c
ON c.DC = t.DC
LEFT JOIN (
SELECT DC, STRING_AGG(StorageLocation, ',') WITHIN GROUP (ORDER BY StorageLocation) StorageLocation
FROM tablename
GROUP BY DC
) s ON s.DC = c.DC AND s.StorageLocation = c.StorageLocation
ORDER BY t.ID, t.DC, t.StorageLocation;
参见demo。
您可以使用STRING_AGG
查看数据是否完整。例如:
select
id, dc, location,
case when
(
select t.dc + ':' + string_agg(t2.location, ',') within group (order by t2.location)
from mytable t2
where t2.id = t.id and t2.dc = t.dc
) in ('DC01:ABC,BCA,DCA', 'DC02:ABC,BCA', 'DC03:ABC,DCA') then
'GOOD'
else
'BAD'
end as status
from mytable t
order by id, dc, location;
子查询是必要的,因为在 SQL 服务器中还没有 STRING_AGG
的分析版本。