J'ai deux tables avec des noms de colonne similaires et je dois renvoyer des enregistrements de la table de gauche qui ne se trouvent pas dans la table de droite? J'ai une clé primaire (colonne) qui m'aidera à comparer les deux tableaux. Quelle jointure est préférée?
Si vous demandez T-SQL, examinons d’abord les principes fondamentaux. Il existe trois types de jointures, chacune avec son propre ensemble de phases de traitement logique, à savoir:
cross join
est le plus simple de tous. Il implémente une seule phase de traitement de requête logique, un Cartesian Product
. Cette phase fonctionne sur les deux tables fournies en entrée de la jointure et produit un produit cartésien des deux. C'est-à-dire que chaque ligne d'une entrée correspond à toutes les lignes de l'autre. Ainsi, si vous avez m lignes dans une table et n lignes dans l’autre, vous obtenez m × n lignes dans le résultat.Inner joins
: Ils appliquent deux phases de traitement de requête logique: A Cartesian product
entre les deux tables d'entrée comme dans une jointure croisée, puis filters
lignes en fonction d'un prédicat que vous spécifiez dans la clause ON
(également appelé Join condition
).Vient ensuite le troisième type de jointure, Outer Joins
:
Dans un outer join
, vous marquez une table en tant que table preserved
en utilisant les mots-clés LEFT OUTER JOIN
, RIGHT OUTER JOIN
ou FULL OUTER JOIN
entre les noms de table. Le mot clé OUTER
est optional
. Le mot clé LEFT
signifie que les lignes du left table
sont préservées; le mot clé RIGHT
signifie que les lignes du right table
sont préservées; et le mot clé FULL
signifie que les lignes des tables both
et left
et right
sont préservées.
La troisième phase de traitement d'une requête logique d'un outer join
identifie les lignes de la table préservée qui ne trouvaient pas de correspondances dans l'autre table en fonction du prédicat ON
. Cette phase ajoute ces lignes à la table de résultats générée par les deux premières phases de la jointure et utilise les marques NULL
comme espaces réservés pour les attributs du côté non préservé de la jointure dans ces lignes externes.
Examinons maintenant la question suivante: Pour renvoyer les enregistrements de la table de gauche qui ne se trouvent pas dans la table de droite, utilisez Left outer join
et filtrez les lignes avec les valeurs NULL
pour les attributs du côté droit de la jointure.
Essaye ça
SELECT f.*
FROM first_table f LEFT JOIN second_table s ON f.key=s.key
WHERE s.key is NULL
Pour plus d’informations, consultez cet article: Jointures dans Sql Server
J'aime aussi utiliser NOT EXISTS. Quand il s’agit de la performance, si l’index est correct, il devrait fonctionner comme un LEFT JOIN ou meilleur. De plus, il est plus facile à lire.
SELECT Column1
FROM TableA a
WHERE NOT EXISTS ( SELECT Column1
FROM Tableb b
WHERE a.Column1 = b.Column1
)
Je ne peux rien ajouter d'autre qu'un exemple de code aux deux autres réponses: cependant, je trouve qu'il peut être utile de le voir en action (les autres réponses, à mon avis, sont meilleures parce qu'elles l'expliquent).
DECLARE @testLeft TABLE (ID INT, SomeValue VARCHAR(1))
DECLARE @testRight TABLE (ID INT, SomeOtherValue VARCHAR(1))
INSERT INTO @testLeft (ID, SomeValue) VALUES (1, 'A')
INSERT INTO @testLeft (ID, SomeValue) VALUES (2, 'B')
INSERT INTO @testLeft (ID, SomeValue) VALUES (3, 'C')
INSERT INTO @testRight (ID, SomeOtherValue) VALUES (1, 'X')
INSERT INTO @testRight (ID, SomeOtherValue) VALUES (3, 'Z')
SELECT l.*
FROM
@testLeft l
LEFT JOIN
@testRight r ON
l.ID = r.ID
WHERE r.ID IS NULL
Cette page donne une ventilation correcte des différents types de jointures, ainsi que des visualisations de diagrammes venn pour vous aider à bien visualiser la différence entre les jointures.
Comme les commentaires l'indiquent, il s'agit d'une requête assez élémentaire. Vous devriez donc essayer de comprendre les différences entre les jointures et leur signification réelle.
Découvrez http://blog.codinghorror.com/a-visual-explanation-of-sql-joins/
Vous recherchez une requête telle que:
DECLARE @table1 TABLE (test int)
DECLARE @table2 TABLE (test int)
INSERT INTO @table1
(
test
)
SELECT 1
UNION ALL SELECT 2
INSERT INTO @table2
(
test
)
SELECT 1
UNION ALL SELECT 3
-- Here's the important part
SELECT a.*
FROM @table1 a
LEFT join @table2 b on a.test = b.test -- this will return all rows from a
WHERE b.test IS null -- this then excludes that which exist in both a and b
-- Returned results:
2
sélectionnez * dans la table de gauche sans champ clé (sélectionnez le champ clé dans la table de droite)
Ceci est un exemple de travail dans la vie réelle, on m'a demandé de fournir une liste d'utilisateurs qui ont acheté de notre site au cours des 6 derniers mois mais pas au cours des 3 derniers mois.
Pour moi, la façon la plus compréhensible à laquelle je puisse penser est la suivante:
--Users that bought from us 6 months ago and between 3 months ago.
DECLARE @6To3MonthsUsers table (UserID int,OrderDate datetime)
INSERT @6To3MonthsUsers
select u.ID,opd.OrderDate
from OrdersPaid opd
inner join Orders o
on opd.OrderID = o.ID
inner join Users u
on o.BuyerID = u.ID
where 1=1
and opd.OrderDate BETWEEN DATEADD(m,-6,GETDATE()) and DATEADD(m,-3,GETDATE())
--Users that bought from us in the last 3 months
DECLARE @Last3MonthsUsers table (UserID int,OrderDate datetime)
INSERT @Last3MonthsUsers
select u.ID,opd.OrderDate
from OrdersPaid opd
inner join Orders o
on opd.OrderID = o.ID
inner join Users u
on o.BuyerID = u.ID
where 1=1
and opd.OrderDate BETWEEN DATEADD(m,-3,GETDATE()) and GETDATE()
Maintenant, avec ces 2 tables dans mes mains, je n'ai besoin que de récupérer les utilisateurs de la table @ 6To3MonthsUsers qui ne figurent pas dans @ Last3MonthsUsers table.
Il y a 2 façons simples d'y parvenir:
Utiliser la jointure gauche:
select distinct a.UserID
from @6To3MonthsUsers a
left join @Last3MonthsUsers b
on a.UserID = b.UserID
where b.UserID is null
Pas dedans:
select distinct a.UserID
from @6To3MonthsUsers a
where a.UserID not in (select b.UserID from @Last3MonthsUsers b)
Les deux méthodes me permettent d'obtenir le même résultat, personnellement, je préfère la deuxième méthode, car elle est plus lisible.