【问题标题】:Check equals between multiple columns values in a row?检查一行中多个列值之间的相等?
【发布时间】:2018-05-13 23:13:00
【问题描述】:

在这里快速提问

我有一张这样的桌子

COLUMN_1 COLUMN_2 COLUMN_3 COLUMN_4 COLUMN_5  SAME
X1       X1       X1       X1       X1        X1
X1       X2       X1       X1       X3        DIFFERENT
X1       NULL     X1       X1       NULL      X1
X1       NULL     X2       NULL     X3        DIFFERENT

所以基本上我想知道column_1和column 5之间的所有colums是否相同,然后得到一个具有值的列(第1行)。如果不是所有列都不同,那么得到一个不同的列(第 2 行)。这些行可以包含空值(第 3 行、第 4 行),但不会影响标志。

顺便说一句,列类型是 STRING。

我希望在 teradata 或 oracle 中执行此操作。

非常感谢

PS:Column_1 不为空,它可以包含从 x1 到 x5 的值。 Column_2 到 Column_5 可以为空。

【问题讨论】:

  • 如果全部为 NULL 怎么办?
  • column_1 总是 x1 吗?如果所有列都是 X3,是 Same = X3?
  • 第 1 列不为空
  • column_1 可以是 x1、x2、x3、x4、x5。基本上,是的。

标签: sql oracle teradata


【解决方案1】:

根据您正在使用的实际数据,您可以暂时将数据取消透视为行,这样您的问题就很容易解决。在这里,我假设您的表中有一个名为 row_id 的主键。

使用您的示例数据...

with your_table as(
   select 1 as row_id, 'X1' as c1, 'X1' as c2, 'X1' as c3, 'X1' as c4, 'X1' as c5 from dual union all
   select 2 as row_id, 'X1' as c1, 'X2' as c2, 'X1' as c3, 'X1' as c4, 'X3' as c5 from dual union all
   select 3 as row_id, 'X1' as c1, null as c2, 'X1' as c3, 'X1' as c4, null as c5 from dual union all
   select 4 as row_id, 'X1' as c1, null as c2, 'X2' as c3, null as c4, 'X3' as c5 from dual
)
select * 
  from your_table; 

ROW_ID   C1  C2  C3  C4  C5
------   --  --  --  --  --
1        X1  X1  X1  X1  X1
2        X1  X2  X1  X1  X3
3        X1      X1  X1   
4        X1      X2      X3

使用如下所示的 unpivot 运算符,会将所有非空列值转换为每个自己的记录。请注意输出中如何缺少空值。

select * 
  from your_table unpivot(colval for colname in(c1, c2, c3, c4, c5));

row_id   colname  colval
------   -------  ------
1            C1       X1
1            C2       X1
1            C3       X1
1            C4       X1
1            C5       X1
2            C1       X1
2            C2       X2
2            C3       X1
2            C4       X1
2            C5       X3
3            C1       X1
3            C3       X1
3            C4       X1
4            C1       X1
4            C3       X2
4            C5       X3

...从这里很容易解决您的问题。

select row_id
      ,case when count(distinct colval) = 1 -- There is only one value across columns    
            then min(colval)                -- All are same, just pick one
            else 'DIFFERENT'
        end one_value
  from your_table unpivot (colval for colname in(c1, c2, c3, c4, c5))
 group -- Group by to reassemble the record 
    by row_id 

编辑: 在澄清了 C1 和可空性之后,问题就简单多了:

select case when not c1 = all(c2,c3,c4,c5) then 'DIFFERENT' else c1 end
  from your_table;

但无论如何我都会留下旧答案,因为它解决了所有列都可以为空时的问题。

【讨论】:

  • 非常好的解决方案!
【解决方案2】:

使用触发器你可以这样:

CREATE OR REPLACE TRIGGER TRIGGER1 
BEFORE INSERT OR UPDATE ON TEST 
FOR EACH ROW
BEGIN
  IF :new.COLUMN1= :new.COLUMN2
     AND :new.COLUMN3=:new.COLUMN1
     AND  :new.COLUMN4=:new.COLUMN1
     AND :new.COLUMN5=:new.COLUMN1     

   THEN
    :new.same:='SAME';
    ELSE
    :new.same:='DIFFERENT';

    END IF;

END;

您可以考虑在上述触发器中添加 NULL 条件检查。

【讨论】:

    【解决方案3】:

    当第 1 列定义为 NOT NULL 时,您可以应用以下逻辑:将第 2 列连接到第 5 列并删除第 1 列中出现的任何字符串。当结果为空字符串时,所有列都相等(或 NULL )。

    CASE 
       WHEN OReplace(  Coalesce(COLUMN_2,'')
                     ||Coalesce(COLUMN_3,'')
                     ||Coalesce(COLUMN_4,'')
                     ||Coalesce(COLUMN_5,'')
                     ,COLUMN_1
                     ,'') = ''
       THEN COLUMN_1
       ELSE 'different'
    end
    

    编辑:

    Ups,这太复杂了。简单得多:

    CASE
       WHEN column_1 <> column_2
         OR column_1 <> column_3
         OR column_1 <> column_4
         OR column_1 <> column_5
       THEN 'different'
       ELSE column_1   
    end
    

    【讨论】:

      【解决方案4】:

      您可以考虑在表中添加一个虚拟列:

      alter table your_table add same as(
         case when not column_1 = all(column_2, column_3, column_4, column_5) 
              then 'DIFFERENT' 
              else column_1 
          end
      );
      

      【讨论】:

        猜你喜欢
        • 2017-05-21
        • 1970-01-01
        • 1970-01-01
        • 2018-09-05
        • 1970-01-01
        • 2020-05-24
        • 1970-01-01
        • 1970-01-01
        • 2017-01-23
        相关资源
        最近更新 更多