无法获取具有相同代码类型和相同 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 值时在功能键列中,基于 Zplid
和 CodeTypeId
.
意味着我需要获取功能键中具有 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 = 854838
和 Zplid = 25820
的行,因为它们仅在功能键中有 NULL。
我不会获取带有 CodeTypeId = 987431
和 Zplid = 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
我使用 SQL Server 2012。我无法从 table #gen
获取行,当它们的行至少有一个 NULL 且至少有一个非 NULL 值时在功能键列中,基于 Zplid
和 CodeTypeId
.
意味着我需要获取功能键中具有 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 = 854838
和 Zplid = 25820
的行,因为它们仅在功能键中有 NULL。
我不会获取带有 CodeTypeId = 987431
和 Zplid = 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