快速提问
我有一张这样的表
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和第5列之间的所有列都相同,那么得到一个带有值(第1行)的列。如果不是所有列都不同,那么得到一个不同的列(第2行)。这些行可以包含空值(第3行,第4行),但它们不会影响标志。
BTW,列类型为STRING。
我希望在teradata或oracle中这样做。
非常感谢
PS:Column_1不为null,它可以包含从x1到x5的值。 Column_2到Column_5可以为null。
答案 0 :(得分:2)
根据您使用的实际数据,您可以暂时将数据作为行取消,从那里您的问题很容易解决。在这里,我假设您的表中有一个名为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;
但我总是留下旧答案,因为它解决了所有列都可以为空的问题。
答案 1 :(得分:1)
使用触发器可以这样:
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条件检查。
答案 2 :(得分:0)
当第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
答案 3 :(得分:0)
您可以考虑在表格中添加虚拟列:
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
);