Конкатенация строк в предложении where - PullRequest
2 голосов
/ 05 января 2012

Вчера я опубликовал следующий вопрос: Несколько операторов "in" в предложении where, которые должны совпадать друг с другом

В этом было некоторое обсуждение о функции в 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 ]

8 голосов
/ 05 января 2012

Предположительно, речь идет о динамически генерируемом 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). Наконец, создайте индекс для этого представления в этом столбце. Затем измените свой код, чтобы выбрать из этого нового представления и столбца, а не из базовой таблицы.

4 голосов
/ 05 января 2012

Я бы просто прикусил пулю и четко прописал условия ИЛИ:

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 голосов
/ 05 января 2012

Вы можете преобразовать это конкретное условие предложения 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
2 голосов
/ 05 января 2012

Не забудьте решение с помощью cte's;)

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
2 голосов
/ 05 января 2012

Вы можете использовать JOIN для временной таблицы / таблицы var, которая может быть более точным способом в зависимости от вашего сценария / количества комбинаций:

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
1 голос
/ 05 января 2012

Я не вижу в этом особого смысла (я предпочитаю верхний ответ, за который я также проголосовал), но, поскольку вы просили (ради образования) версию, использующую конкатенацию, следующее будет быстрее, чем кодв вашем вопросе, как он будет использовать индекс по одному из столбцов

select  *
from    property.lease_period
where  
      suite_id in ('CCBG08', 'CCBG14', 'CCCF048')
      AND
      (suite_id + ' ' + lease_id) 
        in (
            ('CCBG08 205059'),
            ('CCBG14 152424'),
            ('CCCF048 150659')
        )
1 голос
/ 05 января 2012

Разве это не то, что оракул предоставляет только краткую форму этого?

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 немного ржавый.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...