我昨天发布了以下问题:Multiple 'in' statements in a where clause that need to match against each other
在此有一些关于Oracle中的一个功能的讨论在Microsoft SQL中不存在,具体的代码行是:
where (suite_id,lease_id) in (('CCBG08','205059'),('CCBG14','152424'),('CCCF048','150659'))
假设我们有一个表(但有更多行):
suite_id lease_id
CCBG08 150659
CCBG14 152424
我在此推断为Microsoft SQL创建以下解决方案:
select *
from property.lease_period
where (suite_id + ' ' + lease_id)
in (
('CCBG08 205059'),
('CCBG14 152424'),
('CCCF048 150659')
)
不幸的是,做这样的事情对性能的影响非常大(因为没有使用索引)。我想知道如何改进它?
答案 0 :(得分:8)
据推测,我们在这里讨论动态生成的SQL,对吧?那么,在这种情况下,为什么不使用长格式:
select *
from property.lease_period
where
(suite_id = 'CCBG08' AND lease_id = '205059') OR
(suite_id = 'CCBG14' AND lease_id = '152424') OR
(suite_id = 'CCCF048' AND lease_id = '150659')
修改的 重新阅读你的原始帖子,我看到这基本上是你开始的,并希望避免。考虑到这一点,您可以通过创建property.lease_period的视图,将您发布的方法(字符串连接值)与索引一起使用,并在该视图中包含计算列(例如,suite_id +''+ lease_id为suite_lease)。最后,在该列上为该视图创建索引。然后更改代码以从此新视图和列中进行选择,而不是基表。
答案 1 :(得分:4)
我会咬紧牙关并明确说明OR条件:
SELECT *
FROM property.lease_period
WHERE (suite_id = 'CCBG08' AND lease_id = '205059')
OR (suite_id = 'CCBG14' AND lease_id = '152424')
OR (suite_id = 'CCCF048' AND lease_id = '150659')
答案 2 :(得分:2)
您可以在临时表/表变量上使用JOIN,这可能是一种更简洁的方式,具体取决于您的方案/组合数量:
DECLARE @data TABLE (suite_id VARCHAR(10), lease_id VARCHAR(10))
INSERT @data VALUES('CCBG08', '205059')
INSERT @data VALUES('CCBG14', '152424')
INSERT @data VALUES('CCCF048', '150659')
select l.*
from property.lease_period l
JOIN @data d ON l.suite_id = d.suite_id AND l.lease_id = d.lease_id
答案 3 :(得分:2)
不要忘记使用cte的解决方案;)
with cte (suite_id, lease_id) as (
select 'CCBG08' , '205059'
union select 'CCBG14' ,'152424'
union select 'CCCF048' , '150659'
)
select *
from cte
JOIN property.lease_period l
ON l.suite_id = cte.suite_id
AND l.lease_id = cte.lease_id
答案 4 :(得分:2)
您可以将WHERE
子句的特定条件转换为这样的连接:
SELECT
…
FROM property.lease_period p
INNER JOIN (
VALUES ('CCBG08','205059'), ('CCBG14','152424'), ('CCCF048','150659')
) x (suite_id, lease_id)
ON p.suite_id = x.suite_id AND p.lease_id = x.lease_id
答案 5 :(得分:1)
这不是oracle提供的简短形式吗?
select *
from property.lease_period
where (suite_id = 'CCBG08' and lease_id = '205059') or
(suite_id = 'CCBG14' and lease_id = '152424') or
(suite_id = 'CCCF048' and lease_id = '150659') or
抱歉,如果这不太正确,我的sql有点生锈。
答案 6 :(得分:1)
我没有看到很多重点(我更喜欢我也赞成的最佳答案),但是因为你已经(为了教育)要求使用串联的版本,以下将比代码更快在你的问题中,因为它会利用其中一列的索引
select *
from property.lease_period
where
suite_id in ('CCBG08', 'CCBG14', 'CCCF048')
AND
(suite_id + ' ' + lease_id)
in (
('CCBG08 205059'),
('CCBG14 152424'),
('CCCF048 150659')
)