检查一行中多列值之间的等于?

时间:2023-01-27 13:17:15

quick question here

这里有个问题

I have a table like this

我有一张这样的桌子

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

So basically what i want to know if all the colums between column_1 and column 5 are the same , then get a column with the value (row 1 ).If not all are the columns are different then get a column with different (row 2) . These rows can contain null values (row 3, row 4) but they do not affect the flag.

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

BTW, The columns type is STRING.

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

Im looking to do this in teradata or oracle.

我希望在teradata或oracle中这样做。

Thanks a lot

非常感谢

PS: Column_1 is not null it can contain values from x1 to x5. Column_2 to Column_5 can be null.

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

4 个解决方案

#1


2  

Depending on the actual data you are working with, you could temporarily unpivot the data as rows, and from there your problem is easy to solve. Here I'm assuming there is a primary key in your table called row_id.

根据您使用的实际数据,您可以暂时将数据作为行进行取消,从那里您的问题很容易解决。这里我假设你的表中有一个名为row_id的主键。

Using your example data...

使用您的示例数据......

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

Using the unpivot operator like below, would turn all non-null column values into each own record. Notice how the null values are missing from the output.

使用如下所示的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

...And from here it is easy to solve your problem.

......从这里可以轻松解决您的问题。

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 

Edit: After clarifications about C1 and nullability, the problem is much simpler:

编辑:在澄清C1和可空性后,问题更加简单:

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

But I'm anyway leaving the old answer, because it solves the problem when all columns are nullable.

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

#2


1  

Using a trigger you can something like this :

使用触发器你可以这样:

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;

You can consider adding NULL condition check as well to the above trigger.

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

#3


0  

When column 1 is defined as NOT NULL you can apply following logic: concatenate columns 2 to 5 and remove any occurance of the string in column 1. When the result is an empty string all columns were equal (or NULL).

当第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

Edit:

编辑:

Ups, this was way too complicated. Much simpler:

起来,这太复杂了。更简单:

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


0  

You can consider adding a virtual column to your table:

您可以考虑向表中添加虚拟列:

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

#1


2  

Depending on the actual data you are working with, you could temporarily unpivot the data as rows, and from there your problem is easy to solve. Here I'm assuming there is a primary key in your table called row_id.

根据您使用的实际数据,您可以暂时将数据作为行进行取消,从那里您的问题很容易解决。这里我假设你的表中有一个名为row_id的主键。

Using your example data...

使用您的示例数据......

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

Using the unpivot operator like below, would turn all non-null column values into each own record. Notice how the null values are missing from the output.

使用如下所示的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

...And from here it is easy to solve your problem.

......从这里可以轻松解决您的问题。

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 

Edit: After clarifications about C1 and nullability, the problem is much simpler:

编辑:在澄清C1和可空性后,问题更加简单:

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

But I'm anyway leaving the old answer, because it solves the problem when all columns are nullable.

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

#2


1  

Using a trigger you can something like this :

使用触发器你可以这样:

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;

You can consider adding NULL condition check as well to the above trigger.

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

#3


0  

When column 1 is defined as NOT NULL you can apply following logic: concatenate columns 2 to 5 and remove any occurance of the string in column 1. When the result is an empty string all columns were equal (or NULL).

当第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

Edit:

编辑:

Ups, this was way too complicated. Much simpler:

起来,这太复杂了。更简单:

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


0  

You can consider adding a virtual column to your table:

您可以考虑向表中添加虚拟列:

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