web-dev-qa-db-fra.com

T-SQL: Comment sélectionner des valeurs dans la liste de valeurs qui ne figurent pas dans la table?

J'ai une liste d'adresses e-mail, certaines d'entre elles sont dans mon tableau, d'autres non. Je veux sélectionner tous les courriels de cette liste et qu'ils soient ou non dans la table.

Je peux obtenir les utilisateurs dont les adresses de messagerie sont dans la table comme ceci:
SELECT u.* FROM USERS u WHERE u.EMAIL IN ('email1', 'email2', 'email3')

Mais comment puis-je sélectionner dans cette liste des valeurs qui n'existent pas dans le tableau?

De plus, comment puis-je sélectionner comme ceci:

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

Merci d'avance.

53
kubilay

Pour 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)  

Pour les versions précédentes, vous pouvez faire quelque chose de similaire avec une table dérivée UNION ALLing les constantes.

/*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)
82
Martin Smith

Vous devez en quelque sorte créer une table avec ces valeurs, puis utiliser NOT IN. Cela peut être fait avec une table temporaire, un CTE (Common Table Expression) ou un Table Values ​​Constructor (disponible dans SQL-Server 2008):

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

Le deuxième résultat peut être trouvé avec un LEFT JOIN ou une sous-requête 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)
9
ypercubeᵀᴹ

Vous devriez avoir une table avec la liste des emails à vérifier. Puis faites cette requête:

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
2
Lamak

Si vous ne souhaitez pas que les courriels figurant dans la liste se trouvent dans la base de données, vous pouvez procéder comme suit:

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)

de cette façon, vous obtiendrez un résultat comme

name | email  | emailadres | existence
-----|--------|------------|----------
NULL | NULL   | [email protected]    | Not exists
Jan  | [email protected] | [email protected]     | Exists

L'utilisation des opérateurs IN ou EXISTS est plus lourde que la jointure gauche dans ce cas.

Bonne chance :)

1
Mark Kremers

Cela devrait fonctionner avec toutes les versions de 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
0
Anju313

Utilisez ceci: - SQL Server 2008 ou version ultérieure

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
Ardalan Shahgholi