Oracle SQL“meta”查询具有特定列值的记录

时间:2011-11-25 17:23:17

标签: sql oracle filtering

我想从一张巨大的表中获取所有记录,其中任何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的字段名称但是应该有一些更优雅的解决方案,不是吗?

2 个答案:

答案 0 :(得分:3)

可能的解决方案:

  1. 规范化表格。你说你不被允许。尝试通过解释好处(性能,编写查询的简易性等)来说服那些禁止这种变化的人。

  2. 编写巨大的丑陋OR查询。您还可以将其与规范化表的查询版本一起打印。添加性能测试(我希望你可以创建另一个测试表或数据库。)

  3. 编写一个程序(使用PL / SQL或其他程序语言),产生可怕的OR查询。 (再次,与优雅版一起打印)

  4. 添加一个名为Any_x_bigger_than_zero的新列,该列自动通过触发器填充01(使用巨大的丑陋OR) 。然后,您只需检查:WHERE Test_x_bigger_than_zero = 1以查看是否有任何行> 0

  5. 与之前相似,但更好的是,使用这样的列创建物化视图。

答案 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的极少数场景之一。现在你有一个相对直接的表来读取,这应该是一个相对简单的查询从这里