检查十个字段中的任意两个是否不同(不是 NULL 或相等)

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

with binomial(10, 2) = 总共 45 个条件?

除了不优雅之外,它似乎很脆弱——而且刚刚调试了一个问题,其中一个长列表中的一个变量有错字,而不仅仅是学术问题。但是,如果这是唯一可行的方法……尽管如果列表扩展到 20 个,那就不那么好了。

在 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;

这假定字段本身不包含逗号;如果是这样,请使用不同的分隔符。

这个想法是为了return一些价值;然后替换该值和逗号,看看是否剩下 NULL/空字符串。

以下脚本将允许您检查所有 10 个值是否不同。如果所有 10 个值都不同,则该行将仅 return-

你可以查看DEMO HERE

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
)

UNPIVOT 列到行,然后 GROUP BY 您的主键和 COUNT 未透视列中的 DISTINCT 值以查看是否有多个唯一值值:

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

输出:

| ID |
| -: |
|  2 |
|  4 |

db<>fiddle here