T-SQL: как выбрать значения в списке значений, которых нет в таблице? - PullRequest
52 голосов
/ 02 февраля 2012

У меня есть список адресов электронной почты, некоторые из них находятся в моей таблице, некоторые нет.Я хочу выбрать все электронные письма из этого списка и указать, есть ли они в таблице или нет.

Я могу получить пользователей, почтовые адреса которых находятся в таблице следующим образом:
SELECT u.* FROM USERS u WHERE u.EMAIL IN ('email1', 'email2', 'email3')

Но как я могу выбрать значения в этом списке, которых нет в таблице?

Более того, как я могу выбрать вот так:

E-Mail | Status
email1 | Exist  
email2 | Exist  
email3 | Not Exist  
email4 | Exist  

Заранее спасибо.

Ответы [ 6 ]

80 голосов
/ 02 февраля 2012

Для SQL Server 2008

SELECT email,
       CASE
         WHEN EXISTS(SELECT *
                     FROM   Users U
                     WHERE  E.email = U.email) THEN 'Exist'
         ELSE 'Not Exist'
       END AS [Status]
FROM   (VALUES('email1'),
              ('email2'),
              ('email3'),
              ('email4')) E(email)  

Для предыдущих версий вы можете сделать что-то похожее с производной таблицей UNION ALL с константами.

/*The SELECT list is the same as previously*/
FROM (
SELECT 'email1' UNION ALL
SELECT 'email2' UNION ALL
SELECT 'email3' UNION ALL
SELECT 'email4'
)  E(email)
9 голосов
/ 02 февраля 2012

Вам нужно как-то создать таблицу с этими значениями, а затем использовать NOT IN. Это можно сделать с помощью временной таблицы, CTE (общего выражения таблицы) или конструктора табличных значений (доступно в SQL-Server 2008):

SELECT email
FROM
    ( VALUES 
        ('email1')
      , ('email2')
      , ('email3')
    ) AS Checking (email)
WHERE email NOT IN 
      ( SELECT email 
        FROM Users
      ) 

Второй результат можно найти с помощью подзапроса LEFT JOIN или EXISTS:

SELECT email
     , CASE WHEN EXISTS ( SELECT * 
                          FROM Users u
                          WHERE u.email = Checking.email
                        ) 
            THEN 'Exists'
            ELSE 'Not exists'
       END AS status 
FROM
    ( VALUES 
        ('email1')
      , ('email2')
      , ('email3')
    ) AS Checking (email)
2 голосов
/ 02 февраля 2012

У вас должна быть таблица со списком писем для проверки.Затем выполните этот запрос:

SELECT E.Email, CASE WHEN U.Email IS NULL THEN 'Not Exists' ELSE 'Exists' END Status
FROM EmailsToCheck E
LEFT JOIN (SELECT DISTINCT Email FROM Users) U
ON E.Email = U.Email
1 голос
/ 02 февраля 2012

Если вы не хотите, чтобы электронные письма в списке, которые есть в базе данных, вы можете сделать следующее:

select    u.name
        , u.EMAIL
        , a.emailadres
        , case when a.emailadres is null then 'Not exists'
               else 'Exists'
          end as 'Existence'
from      users u
          left join (          select 'email1' as emailadres
                     union all select 'email2'
                     union all select 'email3') a
            on  a.emailadres = u.EMAIL)

таким образом, вы получите результат как

name | email  | emailadres | existence
-----|--------|------------|----------
NULL | NULL   | a@b.com    | Not exists
Jan  | j@j.nl | j@j.nl     | Exists

Использование операторов IN или EXISTS в этом случае более тяжелое, чем левое соединение.

Удачи:)

0 голосов
/ 30 января 2016

Используйте это: - SQL Server 2008 или более поздняя версия

SELECT U.* 
FROM USERS AS U
Inner Join (
  SELECT   
    EMail, [Status]
  FROM
    (
      Values
        ('email1', 'Exist'),
        ('email2', 'Exist'),
        ('email3', 'Not Exist'),
        ('email4', 'Exist')
    )AS TempTableName (EMail, [Status])
  Where TempTableName.EMail IN ('email1','email2','email3')
) As TMP ON U.EMail = TMP.EMail
0 голосов
/ 20 мая 2014

Это должно работать со всеми версиями SQL.

SELECT  E.AccessCode ,
        CASE WHEN C.AccessCode IS NOT NULL THEN 'Exist'
             ELSE 'Not Exist'
        END AS [Status]
FROM    ( SELECT    '60552' AS AccessCode
          UNION ALL
          SELECT    '80630'
          UNION ALL
          SELECT    '1611'
          UNION ALL
          SELECT    '0000'
        ) AS E
        LEFT OUTER JOIN dbo.Credentials C ON E.AccessCode = c.AccessCode
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...