标记列中不具有指定组合的项目

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 的分析版本。