我想从一张巨大的表中获取所有记录,其中任何number
列的值都大于0
。最好的方法是什么?
E.g:
/* table structure*/
create table sometable (id number,
somestring varchar2(12),
some_amount_1 number(17,3),
some_amount_2 number(17,3),
some_amount_3 number(17,3),
...
some_amount_xxx number(17,3));
/* "xxx" > 100, and yeah I did not designed that table structure... */
我希望任何一行some_amount_n > 0
(更好的解决方案是首先添加一个字段来显示哪个字段大于零)。
我知道我可以用一个巨大的some_amount_1 > 0 OR some_amount_2 > 0 OR ...
块来写这个(和一些case when
的字段名称但是应该有一些更优雅的解决方案,不是吗?
答案 0 :(得分:3)
可能的解决方案:
规范化表格。你说你不被允许。尝试通过解释好处(性能,编写查询的简易性等)来说服那些禁止这种变化的人。
编写巨大的丑陋OR
查询。您还可以将其与规范化表的查询版本一起打印。添加性能测试(我希望你可以创建另一个测试表或数据库。)
编写一个程序(使用PL / SQL或其他程序语言),产生可怕的OR
查询。 (再次,与优雅版一起打印)
添加一个名为Any_x_bigger_than_zero
的新列,该列自动通过触发器填充0
或1
(使用巨大的丑陋OR
) 。然后,您只需检查:WHERE Test_x_bigger_than_zero = 1
以查看是否有任何行> 0
与之前相似,但更好的是,使用这样的列创建物化视图。
答案 1 :(得分:1)
首先,创建一个表格,将数据分类为更容易阅读的内容......像id,column_name,column_value这样的简单内容。你必须忍受我,因为我在oracle中运行了一段时间,所以这是最重的伪代码:
快速动态sql blurb ...您可以将变量设置为sql语句,然后执行该变量。存在一些安全风险,并且可能在您的环境中禁用此功能...因此请确认您可以先运行此功能。声明一个变量,将变量设置为'select 1'然后使用'execute immediate'来执行存储在变量中的sql。
set var = 'select id, ''some_amount_' || 1 || '', some_amount || 1 || ' from table where some_amount_' || 1 || ' <> 0'
假设我的oracle语法正确...(管道是正确的追加?我认为3个单引号为'''会导致一个变量',你可能需要试用并错误直到你将var设置为):
select id, 'some_amount_1',some_amount_1
from table
where some_amount_1 <> 0
这应该为some_amount_1中的数据库中的每个id选择ID和值。您可以很容易地将其转换为插入语句。
我假设some_amount_xxx有一个上限......下一个技巧是循环这个巨大的声明。再一次,可怕的伪代码:
declare sql_string
declare i and set to 1
for i = 1 to xxx (whatever your xxx is)
set sql_string to the first set var statement we made, replacing the '1' with the i var here.
execute sql
increment i
loop
希望它有意义......它是你想要循环动态sql的极少数场景之一。现在你有一个相对直接的表来读取,这应该是一个相对简单的查询从这里