Sql-Server
返回所有非 NULL 值都相等的行
是否有一個更簡單的 T-SQL 構造來表示“所有這些列在一行上都相等(忽略 NULL)” - 我想說的是有效:
WHERE MIN(a, b, c) = MAX(a, b, c) OR COALESCE(a, b, c) IS NULL
- 這將相當於所有排列的 COALESCE 相等 - 但沒有非聚合 MIN/MAX 函式
3列的替代方案是:
WHERE ( COALESCE(a, b, c) = COALESCE(b, c, a) AND COALESCE(a, b, c) = COALESCE(c, a, b) AND COALESCE(a, b, c) = COALESCE(b, a, c) AND COALESCE(a, b, c) = COALESCE(a, c, b) AND COALESCE(a, b, c) = COALESCE(c, b, a) ) OR COALESCE(a, b, c) IS NULL
即“所有非 NULL 列 a、b、c 必須相等,否則所有列可能為空”
顯然,可以完成 PIVOT/UNPIVOT 實現或複雜的 CASE 語句,但我正在尋找相對簡單的東西。
在這種情況下,列都是整數,所以我想可能有一個數學技巧我可以弄清楚。
我能找到的最緊湊的語法是:
SELECT * FROM @T AS t WHERE EXISTS ( SELECT ISNULL(ISNULL(a, b), c) INTERSECT SELECT ISNULL(ISNULL(b, c), a) INTERSECT SELECT ISNULL(ISNULL(c, a), b) );
基於我的一篇舊部落格文章中的一個想法,該文章描述瞭如何使用
INTERSECT
和替換EXCEPT
比較(如)。a <> b OR (a IS NULL AND b IS NULL)``NOT EXISTS (a INTERSECT b
VALUES(a),(b),(c)
您可以使用或者如果您使用 SQL Server pre 2008 可以對列進行聚合,您可以這樣做SELECT a UNION ALL SELECT b UNION ALL SELECT c
。SELECT * FROM @T WHERE (SELECT MIN(x) FROM (VALUES(a),(b),(c)) AS T(x)) = (SELECT MAX(x) FROM (VALUES(a),(b),(c)) AS T(x)) OR COALESCE(a, b, c) IS NULL;
更新:
看起來應該快一點的東西。
SELECT T.* FROM @T AS T CROSS APPLY ( SELECT MIN(x), MAX(x) FROM (VALUES(T.a),(T.b),(T.c)) AS X(x) ) AS X(MinValue, MaxValue) WHERE X.MinValue = X.MaxValue OR (X.MinValue IS NULL AND X.MaxValue IS NULL);