2 votes

Insertion de lignes pour un nouveau tableau couvrant les combinaisons de colonnes d'identification des tableaux A et B.

Il y a deux tables existantes, et je veux remplir une nouvelle table (appelons-la MiddleTable) avec la combinaison des colonnes ID des tables existantes. Voici la structure de mes tables (simplifiée à l'extrême), le champ IntField n'est pas important car lors de l'insertion, je veux qu'il s'agisse d'une valeur spécifique qui peut ensuite changer d'une manière qui n'a rien à voir avec ce problème.

Tableau A :

ID, Other columns

Tableau B :

ID, Other columns

Table du milieu

TableA_ID, TableB_ID, IntField, Other columns ....

Ma solution est la suivante : existe-t-il un moyen plus simple ou sans inconvénients importants ?

INSERT INTO MiddleTable (TableA_ID, IntField, TableB_ID) 
  SELECT 
      X.TabAID, 0, X.TabBID 
  FROM 
      (SELECT 
           TableA.ID AS TabA_ID, TableB.ID AS TabB_ID 
       FROM 
           TableA, TableB
       EXCEPT 
       SELECT 
           TableA_ID, TableB_ID  
       FROM 
           MiddleTable) X

2voto

User Points 689
INSERT INTO Main_Table(TabA_ID,TabB_ID)
SELECT Table_A.ID,Table_B.ID FROM Table_A CROSS JOIN Table_B 
EXCEPT 
SELECT TabA_ID,TabB_ID FROM Main_Table

1voto

TT. Points 6824

Ce serait équivalent et, pour SQL Server, la manière la plus efficace. C'est-à-dire que si vous avez un INDEX dans MiddleTable avec ID_A, ID_B pour une recherche rapide.

Il utilise également des CROSS JOIN au lieu de la jointure croisée implicite par FROM TableA, TableB . Comme @marc_s l'a déjà souligné, la syntaxe implicite est ancienne, dépréciée et pourrait être supprimée dans les futures versions de SQL Server.


CREATE TABLE #TableA(ID INT, Other NVARCHAR(128));
CREATE TABLE #TableB(ID INT, Other NVARCHAR(128));
CREATE TABLE #Middle(ID_A INT, ID_B INT, intfield INT, Other NVARCHAR(128));
ALTER TABLE -- index for fast lookup
    #Middle
ADD CONSTRAINT 
    PK_middle PRIMARY KEY CLUSTERED (ID_A,ID_B);

INSERT INTO #Middle(ID_A,ID_B,intfield)
SELECT
    A.ID,B.ID,0
FROM
    #TableA AS A
    CROSS JOIN #TableB AS B
WHERE
    NOT EXISTS(
        SELECT 1
        FROM #Middle AS m
        WHERE m.ID_A=A.ID AND m.ID_B=B.ID
    );

Le site NOT EXISTS la condition fera un joint anti-semi gauche pour repérer les lignes existantes afin que ces lignes ne soient pas insérées à nouveau. Pour SQL Server, c'est généralement la méthode la plus efficace.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X