即使记录不存在,如果为NULL则返回GROUP BY CASE的行THEn(...)ELSE(...)

时间:2019-10-17 00:19:19

标签: sql tsql

让我们考虑以下情况。

CREATE TABLE Replicant (Name NVARCHAR(10),Gen INT);
INSERT INTO Replicant VALUES ('tymtam', 2), ('Roy', 6);

SELECT   
    CASE WHEN Gen < 10 THEN '<10' ELSE '>=10' END as 'Gen', 
    count(*) as 'Count' 
FROM Replicant
GROUP BY CASE WHEN Gen < 10 THEN '<10' ELSE '>=10' END;

结果是一行:

Gen Count
<10 2

我可以提高查询的复杂度,以便使ELSE情况为零吗?

Gen  Count
<10  2
>=10 0

更新2

我的鉴别符为“为空”

SELECT   CASE WHEN Gen IS NOT NULL THEN 'Known' ELSE 'Unknown' END as 'Gen', count(*) as 'Count' FROM Replicant
GROUP BY CASE WHEN Gen IS NOT NULL THEN 'Known' ELSE 'Unknown' END;

结果是

Gen     Count
Known   2

我很渴望

Gen     Count
Known   2
Unknown 0

更新1

我的情况是,我有不同代复制品的成对查询(指标):

INSERT INTO [dbo].[Metrics] (...) SELECT
'Metric X for >=10' as 'Name',
COUNT(*) AS 'Count',
(80_char_expression) AS 'Sum',
(80_char_expression) AS 'Min',
(80_char_expression) AS 'Max', 
0 AS 'StandardDeviation'
FROM Replicant  
WHERE TimestampUtc > DATEADD(WEEK, -1, Current_Timestamp)
AND Gen >= 10

INSERT INTO [dbo].[Metrics] (...) SELECT
'Metric X for <10' as 'Name',
--7 lines repeated from the 1st query
AND Gen < 10

即使没有记录,我也希望有一个选择插入两行。

2 个答案:

答案 0 :(得分:0)

您可以尝试使用UNOIN ALL为您的得分做一个比较表,然后进行outer join

查询1

SELECT t1.word,
       COUNT(Name) 'Count'
FROM
(
SELECT '<10' word,9 maxval,0 minval
UNION ALL
SELECT '>=10' word,2147483646 maxval,10 minval
) t1 LEFT JOIN Replicant on Gen BETWEEN t1.minval AND t1.maxval
GROUP BY t1.word

Results

| word | Count |
|------|-------|
|  <10 |     2 |
| >=10 |     0 |

答案 1 :(得分:0)

您可以使用left join

SELECT v.Gen, COUNT(r.gen) as cnt
FROM (VALUES (NULL, 10, '<10'),
             (10, NULL, '>=10')
     ) v(lo, hi, gen) LEFT JOIN
     Replicant r
     ON (r.gen >= v.lo OR v.lo IS NULL) AND
        (r.gen < v.hi OR v.hi IS NULL)
GROUP BY v.gen;

您还可以使用条件聚合和不可透视:

select v.*
from (select sum(case when r.gen < 10 then 1 else 0 end) as gen_1,
             sum(case when r.gen >= 10 then 1 else 0 end) as gen_2
      from replicant r
     ) r cross apply
     (values (gen_1, '<10'), (gen_2, '>=10')
     ) v(cnt, gen);