如何将SQL服务器中的单行“传播”为多行?

时间:2018-03-10 01:39:14

标签: sql sql-server

我有一个名为'counts'的表,它以下列形式返回行:

SELECT Name,
       PassCount,
       WarningCount,
       FailCount
FROM counts

╔════════════════════════════════════════════╗
║ Name  PassCount   WarningCount   FailCount ║
╠════════════════════════════════════════════╣
║ Jeff  12          2              0         ║
║ Dan   0           0              1         ║
║ Mike  0           0              0         ║
╚════════════════════════════════════════════╝

我想要实现的是“扩展”查询的结果,使得在多个PassCount,WarningCount,FailCount字段中包含非零值的任何行都为每个非零都有一个单独的行在所述计数中出现的值和在其他地方填写的零。我希望得到如下结果,但我对SQL Server缺乏经验,并且真的不知道如何实现这一目标。

╔════════════════════════════════════════════╗
║ Name  PassCount   WarningCount   FailCount ║
╠════════════════════════════════════════════╣
║ Jeff  12          0              0         ║
║ Jeff  0           2              0         ║
║ Dan   0           0              1         ║
║ Mike  0           0              0         ║
╚════════════════════════════════════════════╝

正如您所看到的,包含名称Jeff的行已“扩散”为两行,因为它具有非零的PassCount和WarningCount。希望这有一定道理。我感谢任何帮助!

2 个答案:

答案 0 :(得分:0)

只需使用UNION ALL并检查<>每列0

SELECT Name,
       PassCount,
       WarningCount = 0,
       FailCount = 0
FROM counts
WHERE  PassCount <> 0
union all
SELECT Name,
       PassCount = 0,
       WarningCount,
       FailCount = 0
FROM counts
WHERE WarningCount <> 0
union all
SELECT Name,
       PassCount = 0,
       WarningCount = 0,
       FailCount
FROM counts
WHERE FailCount <> 0

答案 1 :(得分:0)

我相信您想要的查询如下所示:

SELECT Name, PassCount, 0 as WarningCount, 0 as FailCount
FROM counts
WHERE PassCount > 0
UNION ALL
SELECT Name, 0 as PassCount, WarningCount, 0 as FailCount
FROM counts
WHERE WarningCount > 0
UNION ALL
SELECT Name, 0 as PassCount, 0 as WarningCount, FailCount
FROM counts
WHERE FailCount > 0
UNION ALL
SELECT NAME, 0, 0, 0
WHERE PassCount = 0 AND WarningCount = 0 AND FailCount = 0;

如果我想将结果分成多行,我会做这样的事情:

SELECT c.name, v.col, v.val
FROM Counts c CROSS APPLY
     (VALUES ('PassCount', c.PassCount), ('WarningCount', c.WarningCount),
             ('FailCount', c.FailCount)
     ) v(col, val)
WHERE v.val > 0;

但是,“Mike”不会出现在结果中。