Включение объединенного поля в SQL-выражение WHERE ... IN - PullRequest
0 голосов
/ 04 мая 2019

У меня есть оператор SQL, который создает объединенное поле. Как тогда использовать это объединенное поле как часть предложения WHERE ... IN? Посмотрите код ниже, который в настоящее время не работает. SQL работает, когда я удаляю все со второго «и» вниз.

SELECT *, a.LastName + a.FirstName as LastFirst
FROM MST_MEMBER_DEMOGRAPHICS as a
WHERE a.GroupID = 'abcCompany'
And 
a.PersonType = 'D'
and 
LastFirst in
('LastName1FirstName1','LastName2FirstName2','LastName3FirstName3',.....etc)

Ответы [ 2 ]

1 голос
/ 04 мая 2019

Вы не можете использовать значение связанного текста LastFirst в WHERE, поскольку "логический" порядок оценки запроса SQL SELECT на самом деле FROM > WHERE > GROUP BY > HAVING > SELECT > ORDER BY, поэтому выражения, сделанные в части SELECT, не отображаютсяне может использоваться нигде, кроме части ORDER BY (хотя некоторые СУБД, такие как MySQL, допускают использование псевдонимов выражений, концептуально это то же самое, что и использование внешнего запроса).

Я рекомендую не использовать WHERE x IN ( a, b, c, ... ) в вашемпример, потому что это не «правильно» (см. мои заметки ниже относительно ложных срабатываний) - но главным образом потому, что это альтернативное представление оператора OR, когда вы действительно хотите OR ( x AND y ).

Я отмечаю, что WHERE IN обычно вообще не работают с параметрами (так как каждый элемент IN должен быть своим собственным параметром), вам придется использовать (подверженный SQL-инъекциям) динамический SQL, и в этом случае вы должны использовать ( x = a1 AND y = b1 ) OR ( x = a2 AND y = b2 ) OR ...выражения как SARGable и будут работать LOT быстрее.

(отмечу, что в MS SQL Server план выполнения для x IN ( a, b, c ) идентичен( x = a OR x = b OR x = c )).

Другая причина не выполнять конкатенацию строк, как это, из-за риска ложных срабатываний: (Предупреждение: надуманный пример) Предположим, у вас есть два человека: John Smith и Johns Mith -использование вашего подхода будет означать, что оба человека будут соответствовать запросу для любого имени.

Так что я бы сделал это так:

SELECT
    *,
FROM
    MST_MEMBER_DEMOGRAPHICS AS a
WHERE
    a.GroupID = 'abcCompany'
    AND
    a.PersonType = 'D'
    AND
    (
        ( a.LastName = 'LastName1' AND a.FirstName = 'FirstName1' )
        OR
        ( a.LastName = 'LastName2' AND a.FirstName = 'FirstName2' )
        OR
        ( a.LastName = 'LastName3' AND a.FirstName = 'FirstName3' )
    )
1 голос
/ 04 мая 2019

Вы можете повторить выражение, использовать подзапрос или CTE:

SELECT md.*, (md.LastName + md.FirstName) as LastFirst
FROM MST_MEMBER_DEMOGRAPHICS md
WHERE md.GroupID = 'abcCompany' AND
      md.PersonType = 'D' AND
      (md.LastName + md.FirstName) IN ('LastName1FirstName1', 'LastName2FirstName2', 'LastName3FirstName3', .....etc)

Но мой предпочтительный метод - боковое соединение:

SELECT md.*, v.LastFirst
FROM MST_MEMBER_DEMOGRAPHICS md CROSS JOIN
     (VALUES (md.LastName + md.FirstName)) v(LastFirst)
WHERE md.GroupID = 'abcCompany' AND
      md.PersonType = 'D' AND
     v.LastFirrst IN ('LastName1FirstName1', 'LastName2FirstName2', 'LastName3FirstName3',.....etc)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...