2013-12-11 37 views
3

这样的查询作为标题看起来像这样我猜:一个选择多个记录由复合键

select * from table t where (t.k1='apple' and t.k2='pie') or (t.k1='strawberry' and t.k2='shortcake') 
... --10000 more key pairs here 

这看起来相当冗长我。任何更好的选择? (目前使用SQLite,可能会使用MYSQL/Oracle的。)

回答

2

可以使用例如这对甲骨文,我认为如果你使用普通的连击(),而不是甲骨文||在其他数据库上,它也可以工作(因为它只是与IN列表进行字符串比较)。请注意,这样的查询可能会有不理想的执行计划。

SELECT * 
FROM 
    TABLE t 
WHERE 
    t.k1||','||t.k2 IN ('apple,pie', 
         'strawberry,shortcake'); 

但是,如果您将您的值列表存储在其他表中,则Oracle还支持以下格式。

SELECT * 
FROM 
    TABLE t 
WHERE (t.k1,t.k2) IN (SELECT x.k1, x.k2 FROM x); 
+0

谢谢。我正在考虑你的第二个解决方案,但另一个将在未来增长的小型应用程序的10万行表格看起来太耗费资源。至于第一个,你建议为我的原始方法生成代码在性能方面更好? – zeller

+0

我不太确定,大量的OR列表没有提示任何好的东西。试试Ronnis建议的解决方案,如果它适用于您的数据库。我试过了,它显然也适用于Oracle。 – tvm

1
SELECT * FROM tableName t 
WHERE t.k1=(CASE WHEN t.k2=VALUE THEN someValue 
        WHEN t.k2=otherVALUE THEN someotherValue END) 

- SQL FIDDLE

+0

我不完全理解很遗憾这个样子......这如何处理多个复合键? – zeller

+0

我已经测试过SQL Server的查询。我正在考虑表格有两列k1和k2的一般场景。 –

+0

好吧。不幸的是,这仍然随着输入的大小而增长。有没有什么办法可以用'in'来做到这一点,所以唯一的增长部分是输入? – zeller

2
select * from table t 
where (t.k1+':'+t.k2) 
in ('strawberry:shortcake','apple:pie','banana:split','etc:etc') 

这在大多数的,因为它串联的情况下工作,并作为一列

场外,你需要选择一个合适的分离器,这将永远不会在K1的价值发现在和k2。例如对于例如 如果k1和k2的类型为int,则可以将任何字符作为分隔符

2

不要害怕冗长的语法。级联技巧可以轻易搞乱选择性估计,甚至阻止数据库使用索引。

这是另一种语法,可能会或可能不会在您的数据库中工作。

select * 
    from table t 
where (k1, k2) in(
      ('apple',  'pie') 
      ,('strawberry', 'shortcake') 
      ,('banana',  'split') 
      ,('raspberry', 'vodka') 
      ,('melon',  'shot') 
     ); 

最后的评论是,如果你发现自己想提交1000个值过滤器,你应该最有可能的一种不同的方法都在一起:)

+0

sql server不支持这个,请你举个例子RDBMS支持上面的语法谢谢 –

+0

Oracle支持这个语法。 – Ronnis