按复合键选择多个记录

时间:2013-12-11 08:42:07

标签: sql

标题中的这样一个查询看起来像我猜的那样:

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。)

4 个答案:

答案 0 :(得分:3)

你可以在Oracle上使用这个例子,我假设如果你使用常规的concatenate()而不是Oracle的||在其他数据库上,它也可以工作(因为它只是与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 );

答案 1 :(得分: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 :(得分:2)

不要害怕冗长的语法。连接技巧很容易搞乱选择性估计,甚至阻止数据库使用索引。

以下是您的数据库中可能有效或无效的另一种语法。

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

最后的评论是,如果您发现自己想要提交1000个值作为过滤器,那么您最有可能一起寻找不同的方法:)

答案 3 :(得分:1)

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

- SQL FIDDLE