我遇到了一个我有表结构的场景:
Column0 Column1 Column2 Column3 Column4 Column5
100 U V X Y Z
我需要找到:
100
= U
,V
,X
,Y
或Z
。 100
= X
+ Y
+ Z
+ V
100
= X
+ Y
100
= V
+ Z
有关如何实现这一目标的任何建议?
案例陈述将永远写下来。我不写PL / SQL代码,但我对它很熟悉。
答案 0 :(得分:3)
撰写Case
声明并不像您所暗示的那样难。我在大约20秒内使用文本编辑器生成了以下Case
语句,它应该处理示例中的所有情况:
Select Case
When Column0 = Column1 Then 1
When Column0 = Column2 Then 1
When Column0 = Column3 Then 1
When Column0 = Column4 Then 1
When Column0 = Column5 Then 1
When Column0 = Column1 + Column2 Then 1
When Column0 = Column1 + Column3 Then 1
When Column0 = Column1 + Column4 Then 1
When Column0 = Column1 + Column5 Then 1
When Column0 = Column2 + Column3 Then 1
When Column0 = Column2 + Column4 Then 1
When Column0 = Column2 + Column5 Then 1
When Column0 = Column3 + Column4 Then 1
When Column0 = Column3 + Column5 Then 1
When Column0 = Column4 + Column5 Then 1
When Column0 = Column1 + Column2 + Column3 Then 1
When Column0 = Column1 + Column2 + Column4 Then 1
When Column0 = Column1 + Column2 + Column5 Then 1
When Column0 = Column1 + Column3 + Column4 Then 1
When Column0 = Column1 + Column3 + Column5 Then 1
When Column0 = Column1 + Column4 + Column5 Then 1
When Column0 = Column2 + Column3 + Column4 Then 1
When Column0 = Column2 + Column3 + Column5 Then 1
When Column0 = Column2 + Column4 + Column5 Then 1
When Column0 = Column3 + Column4 + Column5 Then 1
When Column0 = Column1 + Column2 + Column3 + Column4 Then 1
When Column0 = Column1 + Column2 + Column3 + Column5 Then 1
When Column0 = Column1 + Column3 + Column4 + Column5 Then 1
When Column0 = Column2 + Column3 + Column4 + Column5 Then 1
When Column0 = Column1 + Column2 + Column3 + Column4 + Column5 Then 1
Else 0
End As SumOfOtherColumns
From YourTable
答案 1 :(得分:0)
即使答案已经被接受,这是我的替代解决方案。在性能方面,很可能更糟糕(待测试)但我认为值得展示的原因如下:
正如您所看到的,有5列,很容易错过一些案例,只有31个案例需要检查。如果添加一列,则为63checks,下一个为127 ...您不必担心这里因为它会动态生成所有情况
另一个有趣的一点是,如果您有兴趣查看每一行的详细信息及其匹配的原因,那么查询就可以免费使用。你只需要选择子视图
最后一点是,我认为它在学术上很有趣。解决方案包含UNPIVOTing数据,递归自连接,动态动态表达式评估。当然,我不是客观的,但这很有趣:)
--Table and data to test the query
create table my_table ( column0 number, column1 number, column2 number,
column3 number, column4 number, column5 number );
INSERT INTO my_table values (100,20,20,10,40,10); -- must match on the sum of 5 columns
INSERT INTO my_table values (100,50,200,300,150,250); -- must not match
INSERT INTO my_table values (100,50,50,100,150,250); -- must match twice ( on col1+col2 and col3 )
-- If your table has a unique key, you can remove the datas_with_id and put
-- your table directly in the unpivoted_data subquery
with datas_with_id as ( select rowid as row_id, t.* from my_table t),
unpivoted_data as ( select row_id, column0 as sum_to_check, column_name, column_value
from datas_with_id
unpivot ( column_value for column_name in (column1,column2,column3,column4,column5))),
calculated_sum as ( select row_id, xmlquery(sys_connect_by_path(u.column_value,'+')||' = '|| sum_to_check
returning content).getStringVal() result
from unpivoted_data u connect by nocycle prior column_name>column_name
and prior row_id=row_id and level < 6)
select * from my_table where rowid in ( select row_id from calculated_sum where result = 'true' )
如果你想添加另一列,请在unpivot子句中添加,在级别加1并且你很好
如果添加sys_connect_by_path(u.column_name,'+')||' ='||在calculate_sum中sum_to_check,您可以看到匹配的每个公式
答案 2 :(得分:0)
在这里,我写了一些你可以动态使用它的代码
1 - 首先我创建表并为其生成一行
create table my_table ( column0 number, column1 number, column2 number,
column3 number, column4 number, column5 number );
INSERT INTO my_table values (100,20,20,10,40,10);
2 - 创建类型如下行
create or replace type Key_Value_Typ as object
(
column_name varchar2(100),
column_val varchar2(100)
)
3 - 你可以在这里看到一个例子
declare
lv_count number;
lv_row my_table%rowtype;
type my_list is table of Key_Value_Typ;
list1 my_list;
------------------------------------------------------------
-- function for control column condition
function check_fun(
lv_list my_list,
-- the function input is array of key value include column name and column value
-- you can implement your code here, for example as input parameter declare your own parameters
-- for example
-- lv_column0 my_table.column0%type;
lv_where varchar2
-- the condition that you want check it
) return number is
lv_str varchar2(200);
lv_count number;
begin
lv_str := lv_where;
for i in 1 .. lv_list.count Loop
lv_str := replace(lv_str,
lv_list(i).column_name,
lv_list(i).column_val);
ENd Loop;
execute immediate 'select count(*) from dual where ' || lv_str
into lv_count;
-- if the function return 1 result is true and o means result is false
return lv_count;
end check_fun;
------------------------------------------------------------
begin
-- fetch data from my_table and get one of them
select * into lv_row from my_table where column0 = 100;
-- create list of data include columns and values
list1 := my_list(Key_Value_Typ('column0', lv_row.column0),
Key_Value_Typ('column1', lv_row.column1),
Key_Value_Typ('column2', lv_row.column2),
Key_Value_Typ('column3', lv_row.column3),
Key_Value_Typ('column4', lv_row.column4),
Key_Value_Typ('column5', lv_row.column5));
lv_count := check_fun(list1, 'column0=column1+column2+column3+column4+column5');
dbms_output.put_line('result ()' || lv_count);
end;