gpt4 book ai didi

sql-server - SQL Server 分组将 null 视为等于所有值

转载 作者:行者123 更新时间:2023-12-03 00:52:53 27 4
gpt4 key购买 nike

在 SQL Server 中,我尝试按 id 对匹配行进行分组。 Null 被视为通配符。

说明:匹配行是什么意思?

匹配行意味着——只要两行的所有列都匹配。

匹配列平均值 - 每个值具有相同值 ('A' = 'A') 或空值 ('A'/'B'/'C'/... = NULL)。

在我的例子中:

第 1 行与第 2 行匹配 - 因为:

First column: 'A' = 'A'
Second column: 'B' = NULL
Third column: NULL = 'C'

第 1 行与第 4 行不匹配:

First column: 'A' = 'A'
Second column: 'B' != 'D'
Third column: NULL = NULL.

比较失败,因为第二列中的值不匹配。

谁能帮我解决 SQL 问题吗?

例如:

用于创建测试表:

create table test_table 
(
id int,
column1 varchar(20),
column2 varchar(20),
column3 varchar(20)
);

insert into test_table (id, column1, column2, column3) values
(1, 'A', 'B', NULL),
(2, 'A',NULL, 'C'),
(3, 'A', 'B', 'D'),
(4, NULL, 'D', NULL),
(5, 'A', 'B', 'D');

以表格为例

enter image description here

这是预期的结果:

group id 1: {1,2}
group id 2: {1,3,5}
group id 3: {2,4}

这些行无法加入一个组:{1,2,3}。

表格中的预期结果示例:

enter image description here

我尝试过这个答案:

   SELECT
T1.id as row_id,
T2.id as row_id
FROM
test_table AS T1
INNER JOIN test_table AS T2 ON
(T1.column1 = T2.column1 OR T1.column1 IS NULL OR T2.column1 IS NULL) AND
(T1.column2 = T2.column2 OR T1.column2 IS NULL OR T2.column2 IS NULL) AND
(T1.column3 = T2.column3 OR T1.column3 IS NULL OR T2.column3 IS NULL)
WHERE
T1.id < T2.id

结果表: enter image description here

所以我可以看到第 1 行与第 2、3、5 行匹配 - 但我看不到第 2 行和 3/5 行无法加入同一组。我想要的是一个结果,我可以看到第 1,3,5 行可以在同一组中,因为它们都匹配,但第 1 行和第 2 行之间的匹配需要在其他组中,因为第 2 行与行不匹配3 和 5。

最佳答案

您可以尝试以下方法:

  • 查找 column1column2column3 中的所有不同值。这些值可能是列中 NULL 值的候选值。
  • 使用生成的不同值生成 NULL 值的所有可能组合
  • 仅选择重复的行
  • 使用 DENSE_RANK() 生成组编号

声明:

;WITH ValuesCTE ([column]) AS (
SELECT column1 FROM #test_table WHERE column1 IS NOT NULL
UNION
SELECT column2 FROM #test_table WHERE column2 IS NOT NULL
UNION
SELECT column3 FROM #test_table WHERE column3 IS NOT NULL
), ReplaceCTE AS (
SELECT
t.id,
CASE WHEN t.column1 IS NULL THEN c1.[column] ELSE t.column1 END AS column1,
CASE WHEN t.column2 IS NULL THEN c2.[column] ELSE t.column2 END AS column2,
CASE WHEN t.column3 IS NULL THEN c3.[column] ELSE t.column3 END AS column3
FROM #test_table t
LEFT JOIN ValuesCTE c1 ON t.column1 IS NULL
LEFT JOIN ValuesCTE c2 ON t.column2 IS NULL
LEFT JOIN ValuesCTE c3 ON t.column3 IS NULL
), DuplicatesCTE AS (
SELECT column1, column2, column3
FROM ReplaceCTE
GROUP BY column1, column2, column3
HAVING COUNT(*) > 1
)
SELECT
r.id,
DENSE_RANK() OVER (ORDER BY r.column1, r.column2, r.column3) AS grp
FROM ReplaceCTE r
RIGHT JOIN DuplicatesCTE d ON (r.column1 = d.column1) AND (r.column2 = d.column2) AND (r.column3 = d.column3)

输出:

id  grp
1 1
2 1
1 2
3 2
5 2
2 3
4 3

关于sql-server - SQL Server 分组将 null 视为等于所有值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54850490/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com