无法获取具有相同代码类型和相同 ZPLID 且功能键同时具有 Null 和值的行?

Can't get rows that have same code type and same ZPLID and feature key have both Null and values?

我使用 SQL Server 2012。我无法从 table #gen 获取行,当它们的行至少有一个 NULL 且至少有一个非 NULL 值时在功能键列中,基于 ZplidCodeTypeId.

意味着我需要获取功能键中具有 NULL 且功能键中具有值但必须相同 CodeTypeId 和相同 Zplid.

的行
create table #gen
(
    CodeTypeId int,
    Zplid  int,
    Zfeaturekey nvarchar(50)
)

insert into #gen 
values (854838, 25820, NULL),
       (849774, 25820, 1502260001),
       (849774, 25820, 1502260001),
       (849774, 25820, 1502260016),
       (849774, 25820, NULL),
       (987431, 26777, 1502270003),
       (987431, 26777, 1502280005),
       (987431, 26777, 1502290001)

这是我需要的结果:

 CodeTypeId    Zplid    Zfeaturekey
 ------------------------------------
     849774    25820    1502260001
     849774    25820    1502260001
     849774    25820    1502260016
     849774    25820    NULL

我不会获取带有 CodeTypeId = 854838Zplid = 25820 的行,因为它们仅在功能键中有 NULL。

我不会获取带有 CodeTypeId = 987431Zplid = 26777 的行,因为它们在功能键中没有 NULL。

这样做的基本方法是 a) 找到同时具有 NULL 和非 NULL 的 CodeTypeID 和 Zplid 的组合 b) 报告 CodeTypeID 和 Zplid

组合的所有行

例如

SELECT g.*
FROM   #gen g
    INNER JOIN 
    (SELECT CodeTypeId, Zplid
      FROM  #gen 
      GROUP BY CodeTypeId, Zplid
      HAVING COUNT(*) > COUNT(Zfeaturekey) 
          AND COUNT(Zfeaturekey) >= 1
    ) AS g_filtered 
        ON g.CodeTypeId = g_filtered.CodeTypeId 
        AND g.Zplid= g_filtered.Zplid 

这是一个db<>fiddle

您可以使用 window 功能。这个想法是计算每个 codetyped 的所有值,并将其与非 null 值的计数进行比较。然后,我们可以使用该信息来确保每组至少有一个非 null 值和一个 null 值。

select *
from (
    select g.*,
        count(*) over(partition by codetypeid) cnt,
        count(zfeaturekey) over(partition by codetypeid) cnt_not_nulls
    from #gen g
) g
where cnt > cnt_not_nulls and cnt_not_nulls > 0

使用CTE可以让代码更简单更直观:

with cte
as(SELECT CodeTypeId, Zplid
      FROM  #gen 
      GROUP BY CodeTypeId, Zplid)

SELECT g.* FROM   #gen g
JOIN cte c
ON g.CodeTypeId = g_filtered.CodeTypeId AND g.Zplid= g_filtered.Zplid
WHERE COUNT(c.*) > COUNT(c.Zfeaturekey) 
          AND COUNT(c.Zfeaturekey) >= 1