代码之家  ›  专栏  ›  技术社区  ›  Charles

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

  •  2
  • Charles  · 技术社区  · 5 年前

    我有一个SQL查询,其中包含10个字段,称它们为v1。。。,v10,我想测试一下。预期的情况是,大多数为空,其余值都相等。有趣的(错误?)Im搜索的情况是至少有两个不相等的非空值。

    有比这更好的方法吗

    v1 != v2 or v1 != v3 or ... v8 != v9 or v8 != v10 or v9 != v10
    

    二项式(10,2)=总共45个条件?

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

    1 回复  |  直到 5 年前
        1
  •  3
  •   MT0    5 年前

    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<>不停摆弄 here

        2
  •  1
  •   Gordon Linoff    5 年前

    在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 /空字符串。

        3
  •  0
  •   mkRabbani    5 年前

    下面的脚本将允许您检查所有10个值是否不同。只有当所有10个值都不同时,该行才会返回-

    你可以查一下 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
    )