[英]Checking whether any two of ten fields are different (not NULL or equal)
我有一個SQL查詢包含(其中包括)十個字段,稱之為v1,...,v10,我想測試它。 預期的情況是大多數是NULL,其余值都是相等的。 我正在搜索的有趣(錯誤?)情況是至少有兩個不相等的非NULL值。
有沒有更好的方法來做到這一點
v1 != v2 or v1 != v3 or ... v8 != v9 or v8 != v10 or v9 != v10
二項式(10,2)=總共45個條件?
除了不優雅之外,它似乎很脆弱 - 剛剛調試了一個問題,長列表中的一個變量有一個錯字,而不僅僅是一個學術問題。 但如果這是唯一可行的方式......但如果列表擴展到20,那就不那么好了。
UNPIVOT
列到行然后GROUP BY
您的主鍵和COUNT
DISTINCT
值在unpivoted列中查看是否有多個唯一值:
Oracle 11安裝程序 :
CREATE TABLE table_name ( id, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10 ) AS
SELECT 1, 'A', 'A', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL FROM DUAL UNION ALL
SELECT 2, 'A', NULL, 'B', NULL, NULL, NULL, NULL, NULL, NULL, NULL FROM DUAL UNION ALL
SELECT 3, 'A', NULL, 'A', 'A', NULL, 'A', 'A', 'A', 'A', 'A' FROM DUAL UNION ALL
SELECT 4, 'A', NULL, 'A', 'A', 'B', NULL, NULL, NULL, NULL, NULL FROM DUAL;
查詢 :
SELECT id
FROM table_name
UNPIVOT ( value FOR name IN ( c1, c2, c3, c4, c5, c6, c7, c8, c9, c10 ) )
GROUP BY id
HAVING COUNT( DISTINCT value ) > 1
輸出 :
\n | ID |\n | - :|\n | 2 |\n | 4 |\n
db <> 在這里小提琴
在Oracle 12c +中,您可以使用橫向連接:
select t.*
from t cross join lateral
(select count(distinct field) as cnt
from (select t.field1 as field from dual union all
select t.field2 as field from dual union all
select t.field3 as field from dual union all
select t.field4 as field from dual union all
select t.field5 as field from dual union all
select t.field6 as field from dual union all
select t.field7 as field from dual union all
select t.field8 as field from dual union all
select t.field9 as field from dual union all
select t.field10 as field from dual
) x
) x
where cnt > 1;
這在早期版本中很痛苦。
這里的方法並不太令人沮喪:
select t.*
from (select t.*,
(field1 || ',' || field2 || ',' || . . . || field10) as fields
from t
) t
where replace(replace(fields, regexp_substr(fields, '[^,]+', 1), ''), ',', '') is not null;
這假定字段本身不包含逗號; 如果是這樣使用不同的分隔符。
想法是返回一些價值; 然后替換該值和逗號,看看是否留下了NULL
/空字符串。
以下腳本將允許您檢查是否所有10個值都不同。 只有當所有10個值不同時,該行才會返回 -
WITH CTE(id,v1,v2,v3,v4,v5,v6,v7,v8,v9,v10)
AS
(
SELECT 1,10,20,30,505,50,60,70,80,90,100 FROM DUAL
),
CTE2 AS
(
SELECT A.ID,A.Value,
DENSE_RANK() OVER (PARTITION BY ID ORDER BY VALUE ) AS D_RANK_NUM
-- As you said you have composit unique column,
-- you can add those columns here for PARTITION BY
-- I have used ID as sample Unique column
FROM
(
SELECT *
FROM CTE
UNPIVOT (value FOR V IN (v1,v2,v3,v4,v5,v6,v7,v8,v9,v10))
)A
)
SELECT * FROM CTE WHERE ID IN(
SELECT ID FROM CTE2 WHERE D_RANK_NUM = 10
)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.