Sélectionnez les lignes de deux tables jointes qui ne sont pas dans une troisième table

J'ai trois tables:

Table1: (EmployeeID int, EmployeeType int)

Table2: (AllowanceID int, EmployeeType int)

Table3: (EmployeeID int, AllowanceID int)

J'ai besoin d'une requête pour sélectionner les lignes jointes des deux tables (Table1, Table2) qui ne résultent pas en troisième (Table3).

J'ai essayé:

Select t1.EmployeeID, t2.AllowanceID From Table2 t2 Inner Join Table1 t1 on t1.EmployeeType = t2.EmployeeType where Not Exists (select 1 From Table3 t3 where t3.EmployeeID = t1.EmployeeID and t3.AllowanceID = t2.AllowanceID ) 

mais pas de succès.

entrez la description de l'image ici

 CREATE TABLE [dbo].[Table1]( [EmployeeID] [int] NULL, [EmployeeType] [tinyint] NULL ) ON [PRIMARY] CREATE TABLE [dbo].[Table2]( [AllowanceID] [int] NOT NULL, [EmployeeType] [int] NULL ) ON [PRIMARY] CREATE TABLE [dbo].[Table3]( [AllowanceID] [int] NULL, [EmployeeID] [int] NULL ) ON [PRIMARY] Insert into Table1 (EmployeeID,EmployeeType) Values (352395, 10), (352396, 16), (352397, 15), (352398, 10), (3523991, 16), (NULL, 16) Insert into Table2 (AllowanceID, EmployeeType) Values (100, 50), (30, 9), (32, 10), (37, 16), (512, 28), (6000, 10) Insert into Table3 (AllowanceID,EmployeeID) Values (NULL, 352400), (32, NULL), (37, NULL), (37, 352395), (6000, 352395), (30, 352396), (32, 352396), (37, 352396), (512, 352396), (6000, 352396), (30, 352397), (32, 352397), (37, 352397), (512, 352397), (6000, 352397), (30, 352398), (32, 352398), (37, 352398), (512, 352398), (6000, 352398), (30, 352399), (32, 352399), (37, 352399), (512, 352399), (6000, 352399) 

Le problème avec votre requête est qu'elle s'attend à ce que null égal à null , ce qui n'est pas le cas .

Pour corriger cela, il suffit de replace t3.EmployeeID = t1.EmployeeID par (t3.EmployeeID = t1.EmployeeID or t1.EmployeeId is null) .

La requête devient:

 select t1.EmployeeID , t2.AllowanceID from Table2 t2 inner join Table1 t1 on t1.EmployeeType = t2.EmployeeType where not exists ( select 1 from Table3 t3 where (t3.EmployeeID = t1.EmployeeID or t1.EmployeeId is null) and t3.AllowanceID = t2.AllowanceID ) 

rextester demo: http://rextester.com/OPRHN52820

 +------------+-------------+ | EmployeeID | AllowanceID | +------------+-------------+ | 352395 | 32 | | 3523991 | 37 | +------------+-------------+ 
 SELECT t1.EmployeeID, t2.AllowanceID FROM Table1 t1 JOIN Table2 t2 ON t1.EmployeeType = t2.EmployeeType LEFT JOIN Table3 t3 ON t3.AllowanceID = t2.AllowanceID AND t3.EmployeeID = t1.EmployeeID WHERE t3.EmployeeID IS NULL 

Vous pouvez essayer d'utiliser une sous-requête avec les tables souhaitées et une jointure à gauche avec la table où vous ne voulez pas find l'logging:

 Select A.EmployeeID, A.AllowanceID FROM (SELECT t1.EmployeeID, t2.AllowanceID From Table2 t2 Inner Join Table1 t1 on t1.EmployeeType = t2.EmployeeType ) A LEFT JOIN t3 ON t3.EmployeeID = A.EmployeeID and t3.AllowanceID = A.AllowanceID WHERE t3.EmployeeID IS NULL and t3.AllowanceID IS NULL 

Si vous utilisez SQL SERVER, utilisez la requête suivante

  SELECT t1.empoyeeId, t2.AllowanceId FROM table1 t1 INNER JOIN table2 t2 ON t2.EmployeeTypeId = t1.EmployeeTypeID EXCEPT SELECT employeeID , allowanceID FROM table2 

Peut-être que vous pourriez essayer EXCEPT, la séquence d'utilisation modifie les résultats

 SELECT t1.EmployeeID , t2.AllowanceID FROM Table2 t2 INNER JOIN Table1 t1 ON t1.EmployeeType = t2.EmployeeType EXCEPT SELECT t3.EmployeeID , t3.AllowanceID FROM Table3 t3 ; SELECT t3.EmployeeID , t3.AllowanceID FROM Table3 t3 EXCEPT SELECT t1.EmployeeID , t2.AllowanceID FROM Table2 t2 INNER JOIN Table1 t1 ON t1.EmployeeType = t2.EmployeeType 

Retourne toutes les valeurs distinctes de la requête à gauche de l'opérateur EXCEPT qui ne sont pas returnnées par la bonne requête. ( ms docs )