2010-04-15 49 views
1

我们已经观察到,似乎有最大数量的可以在SQL的IN子句中作为逗号分隔值传递的ids /变量。为了避免这种情况,我们将所有的id存储在一个表中,并在IN子句中做一个SELECT。但是,这意味着额外的数据库操作来存储和检索id。有没有其他的方式来使用没有SELECT的IN?SQL中IN子句的问题

问候,

萨米尔

+0

你在使用什么数据库服务器?答案取决于这些数据。 – Oded 2010-04-15 14:06:04

+0

SQL Server 2007和Oracle 10.2 – user179056 2010-04-17 10:49:56

回答

2

SQL Server 2008你可以声明表变量,并从客户端或程序之间传递到您的查询。

+0

我的查询是嵌入在j2ee代码中的HQL(hibernate查询语言)。此外,这也需要与Oracle 10.2一起工作。不知道这会工作 – user179056 2010-04-17 10:58:05

2

对于数量适中的数值,我不会认为IN (SELECT ..)在任何rdbms上都会很贵。

你可以INNER JOIN你的ID表或刚刚打破插件:

WHERE X IN (123,456 ...) 
    OR X IN (789,987 ...) 
    ... 
+0

我已经有了变量。使用您的示例 其中X IN(123,456 ...) OR X IN(789,987 ...) 123,456等已经在变量中。但是我不能列出所有12,000个,因为这是有限制的。我试图避免让另一个数据库被保存,然后选择 – user179056 2010-04-17 10:56:13

+0

12,000 ?!你如何将它们传递给in(s)条款? – 2010-04-17 11:13:33

0

如果你把它放在atable你为什么仍然在使用条款,为什么不加入到表?

+0

当然,我可以做到这一点。我的问题的主要目标不是将ID存储在表格中。我已经在变量中有这些ID,但由于有一个可以传入IN查询的变量数量的限制,我不得不将这些ID存储在一个表中(额外的数据库命中)并回收(使用JOIN或IN)(另一个数据库命中 – user179056 2010-04-17 10:53:41

2

与亚历克斯

同意

而不是

Select * From TableA Where ID IN (Select ID from IDTable) 

使用

Select * From TableA 
INNER JOIN IDTable ON TableA.ID = IDTable.ID 

的加入会自动过滤的ID为您服务。

+0

http://explainextended.com/2009/06/16/in-vs-join-vs-exists/ – Quassnoi 2010-04-16 09:09:52

+0

@Quassnoi感谢您的深入文章的链接。在OP的情况下,他们正在存储所以我只是指出,如果他们所做的只是过滤,那么JOIN方式将会是相同的。另外,如果我有选择,我将使用join方法进行可读性和还有一点值得注意的是,当逗号分隔的值在实际处理时会被扩展为一堆OR。 – Jeremy 2010-04-16 13:01:33

+1

@Jemery:当逗号分隔值的'IN'扩展为'CONSTANT SCAN'时,值被击中,这些值被视为正常设置的表格编辑操作(散列连接,合并连接等)。 – Quassnoi 2010-04-16 13:47:15