首页 > 解决方案 > SQL Server 2014 - 列上的 SQL Case 语句

问题描述

这是我的表:

原始表

对于每个唯一的 TID,有 2 条记录。对于唯一的 TID,如果字段中的两条记录都已填充,我想要该字段的名称。例如,对于 T01:Field2 和 Field4 都填充了两个记录。

我目前的方法是创建一个带有逗号分隔值和字段名称的列:

INSERT INTO TEMP
SELECT *, 
       (CASE WHEN COUNT(IIF(Field1 IS NOT NULL,1,NULL)) = 2 THEN 'FIELD1' ELSE 'NO' END) + ',' +
       (CASE WHEN COUNT(IIF(Field2 IS NOT NULL,1,NULL)) = 2 THEN 'FIELD2' ELSE 'NO' END) + ',' +
       (CASE WHEN COUNT(IIF(Field3 IS NOT NULL,1,NULL)) = 2 THEN 'FIELD3' ELSE 'NO' END) + ',' +
       (CASE WHEN COUNT(IIF(Field4 IS NOT NULL,1,NULL)) = 2 THEN 'FIELD4' ELSE 'NO' END) AS ATTR
FROM ORIGINAL_TABLE;

然后我将逗号分隔的列转换为多条记录:

SELECT *, S.ITEMS as ATTRIBUTES
FROM TEMP
CROSS APPLY DBO.SPLIT(ATTR, ',') S
WHERE S.ITEMS NOT LIKE '%NO%'

考虑从上述命令获得的结果的 T101,这给了我输出:

结果我得到

编辑:道歉。它应该是 Field2 而不是 Field1。

这确实为我提供了符合条件的每个唯一 TID 的字段信息,但我希望它更具体。我为超过 100 列的非常大的数据运行此方法,因此这种方法很慢。

有没有办法得到这个?我只显示满足条件的字段及其 T101 中两条记录的值。

预期结果

编辑:道歉。它应该是 Field2 而不是表中的 Field1。

我对SQL相当陌生,任何帮助将不胜感激!

标签: sqlsql-servercase

解决方案


您的问题相当复杂,我不能 100% 确定您真正想要什么。但基于:

对于唯一的 TID,如果字段中的两条记录都已填充,我想要该字段的名称。

您可以取消透视和聚合。假设您的列都具有相似的数据类型,您可以使用:

SELECT t.tId, v.fieldname
FROM ORIGINAL_TABLE t CROSS APPLY
     (VALUES ('Field1', Field1), 
             ('Field2', Field2), 
             ('Field3', Field3), 
             ('Field4', Field4)
     ) v(fieldname, val)
GROUP BY t.tID, v.fieldname
HAVING COUNT(*) = COUNT(v.val)  -- all populated 
             

推荐阅读