2009-06-18 6 views
2

Comment faire une jointure inverse avec plusieurs colonnes clés?Comment INSÉRER en utilisant une JOIN jointe sur plusieurs clés?

Je les suivantes

CREATE TABLE [dbo].[CarList](
[myID] [int] IDENTITY(1,1) NOT NULL, 
[CarColour] [varchar](32) NOT NULL, 
[CarName] [varchar](128) NOT NULL, 
[CarCompany] [varchar](32) NOT NULL, 

CONSTRAINT [PK_CarList] PRIMARY KEY CLUSTERED(
    [myID] ASC, 
    [CarColour] ASC, 
    [CarName] ASC, 
    [CarCompany] ASC 
) 
) 

GO 

INSERT INTO CarList (CarColour, CarName, CarCompany) 
VALUES('blue', 'Abe', 'Ford') 

Ailleurs dans le DB je Dans ce bébé-jouet exemple SqlServer, une table comme

CREATE TABLE [dbo].[NewCars](
[CarColour] [varchar](32) NOT NULL, 
[CarName] [varchar](128) NOT NULL, 
[CarCompany] [varchar](32) NOT NULL, 
) 

GO 

INSERT INTO NewCars (CarColour, CarName, CarCompany) 
SELECT 'blue', 'Abe', 'Ford' 
UNION ALL 
SELECT 'blue', 'Abe', 'GM' 
UNION ALL 
SELECT 'blue', 'Betty', 'Ford' 
UNION ALL 
SELECT 'green', 'Abe', 'Honda' 

Maintenant, je veux insérer les voitures, je ne suis pas déjà ont dans le tableau carliste

Quelque chose comme ...

INSERT INTO CarList (CarColour, CarName, CarCompany) 
SELECT DISTINCT new.CarColour, new.CarName, new.CarCompany 
FROM NewCars new, CarList old 
WHERE new.CarColour <> old.CarColour 
    AND new.CarName <> old.CarName 
    AND new.CarCompany <> old.CarCompany 

Ce qui ne fonctionne pas parce que le « bleu », « Betty », « ligne Ford » va se filtré ...

Si cela était juste un seul identifiant de quelque sorte que ce serait vraiment facile

Pour des raisons que je ne veux pas vraiment aborder, je ne peux pas supprimer des lignes de NewCars qui correspondent à CarList. J'ai aussi besoin de le faire en un seul passage si possible.

[edit] Merci les gars!

Répondre

5

merci pour DDL et DML

Voici une façon

INSERT INTO CarList (CarColour, CarName, CarCompany) 
SELECT DISTINCT * 
FROM NewCars n 
where not exists (select 1 from CarList c where c.CarColour =n.CarColour 
and c.CarName = n.CarName 
and c.CarCompany = n.CarCompany) 

Il y a au moins 4 différentes façon de le faire

  • NOT IN (ne fonctionnera pas pour plus de 1 colonne comme vous avez)
  • NOT EXISTS
  • GAUCHE et DROITE JOIN
  • OUTER APPLY (2005+)
  • SAUF (2005+)

Lire Select all rows from one table that don't exist in another table

+0

NOT IN ne travailler sur plusieurs colonnes dans SQL Server, n'est-ce pas? – Quassnoi

+1

+1: réponse très complète. Agréable. – RBarryYoung

+0

vous auriez besoin d'un tas d'ANDs mais ce serait inefficace. – SQLMenace

5
INSERT 
INTO CarList (CarColour, CarName, CarCompany) 
SELECT CarColour, CarName, CarCompany 
FROM NewCars nc 
WHERE NOT EXISTS 
     (
     SELECT 1 
     FROM CarList cl 
     WHERE cl.CarColor = nc.CarColor 
       AND cl.CarName = nc.CarName 
       AND cl.CarCompany = nc.CarCompany 
     ) 
+0

hehe nous pensons que :-) – SQLMenace

+0

C'était un hier poster dans mon blog :) – Quassnoi

+0

Let's upvote l'un l'autre, c'est un + 10 gratuit après tout! :) – Quassnoi

1
INSERT INTO CarList (CarColour, CarName, CarCompany) 
SELECT DISTINCT new.CarColor, new.CarName, new.CarCompany 
FROM NewCar new 
where not exists (select 0 
     from CarList old 
     WHERE new.CarColour = old.CarColour  
     AND new.CarName = old.CarName  
     AND new.CarCompany = old.CarCompany) 
--This statement matches all that does exists in carlist 
--and insert everything that does not exists in Carlist 
+0

Man vous les gars sont rapides – JuniorFlip

1

Je probablement utiliser:

INSERT INTO CarList(CarColour, CarName, CarCompany) 
SELECT 
    NC.CarColour, 
    NC.CarName, 
    NC.CarCompany 
FROM 
    NewCars NC 
LEFT OUTER JOIN CarList CL ON 
    CL.CarColour = NC.CarColour AND 
    CL.CarName = NC.CarName AND 
    CL.CarCompany = NC.CarCompany 
WHERE 
    CL.MyID IS NULL 
+0

Je préfère cette implémentation. C'est mon soupçon (non prouvé) que les anciennes fonctionnalités sql sont généralement mieux optimisées que les nouvelles fonctionnalités SQL, et les jointures sont à peu près aussi vieux que vous obtenez. Il vaut la peine de comparer les plans d'exécution d'une implémentation de jointure externe à une implémentation qui n'existe pas, car vous semblez avoir les deux disponibles maintenant. – quillbreaker

Questions connexes