J'ai une table contenant des dossiers originaux et des loggings annulés. Les loggings d'origine sont marqués avec le code = 1 et les annulés sont marqués avec le code = 2. Il existe également d'autres types de codes. J'ai besoin de find tous les loggings originaux qui n'ont pas d'logging d'annulation dans le tableau.
Par exemple Table1
id | column2 | column3 | code -- |-------- | ------- | --- 1 | abc | def | 1 2 | xyz | pqr | 1 3 | abc | def | 2
Le résultat de la requête doit être la ligne avec l'ID 2 car elle n'a pas été annulée.
J'essaie d'utiliser l'auto-jointure
select * from table1 t1 join table1 t2 on t1.column1=t2.column1 and t1.column2=t2.column2 and t1.code<t2.code where not (t1.code=1 and t2.code=2)
SELECT * FROM table1 AS t1 WHERE code = 1 AND NOT EXISTS ( SELECT * FROM table1 t2 WHERE t2.code = 2 AND t2.column2 = t1.column2 AND t2.column3 = t1.column3 )
Cette réponse est préférable à l'utilisation de NOT EXISTS
parce qu'elle évite une sous-requête corrélée. Il utilise également des jointures, ce qui signifie qu'il peut tirer parti des indices.
SELECT t1.id, t1.column2, t1.column3, t1.code FROM table1 t1 INNER JOIN ( SELECT column2, column3 FROM table1 GROUP BY column2, column3 HAVING SUM(CASE WHEN code = 2 THEN 1 ELSE 0 END) = 0 ) t2 ON t1.column2 = t2.column2 AND t1.column3 = t2.column3
Vous pouvez utiliser CTE. Trouvez la sum du code tel qu'il est entier. Si elle est supérieure à 1, cela signifie que quelque part pour cette valeur, il y en a 2.
;WITH CTE AS ( Select column1,column3 from Table1 GROUP BY column1,column3 HAVING SUM(code)=1 ) SELECT t.id,CTE.* FROM CTE INNER JOIN @temp t ON t.column1=CTE.column1 AND t.column3=CTE.column3
S'il vous plaît laissez-moi savoir si cela aide.