where子句中的字符串连接

时间:2012-01-04 22:28:09

标签: sql database sql-server-2008 tsql

我昨天发布了以下问题: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')
        )

不幸的是,做这样的事情对性能的影响非常大(因为没有使用索引)。我想知道如何改进它?

7 个答案:

答案 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')
        )