2
votes

Sélectionnez toutes les lignes du tableau A qui ne figurent pas dans le tableau B

Je veux comparer deux tables et obtenir tous les enregistrements de la table A qui ne sont pas dans la table B.

Voici un exemple

SELECT *
FROM TableA A
    LEFT JOIN TableB B ON A.ArticleID = B.ArticleID
WHERE B.ArticleID IS NULL

Alors je veux have:

Articel ID
3
4 

Le code ci-dessous ne vérifie pas le nombre d'entrées et ignore simplement toutes les lignes correspondantes pour qu'il soit:

Articel ID                   
2                            
3                             
5                            

sql

6 commentaires

Quel SGBDR utilisez-vous?


Que se passe-t-il s'il y a quatre 2 dans le tableau A et deux 2 dans le tableau B? Voulez-vous un ou deux 2 dans la sortie?


@maxu. . . Je suis totalement confus. Votre requête renverra des doublons dans A. Quels résultats voulez-vous ?


@maxu s'il y a 2,2,2,2 dans le tableau A quels seraient vos résultats attendus?


@GordonLinoff - ils veulent une sémantique SAUF TOUT


@forpas Table serait 2 2 3 5. J'ai besoin de cela, car je veux résumer un autre champ, qui est contenu dans le tableau A, mais je dois éliminer ces enregistrements spécifiques lorsqu'il y a également des enregistrements dans la table b


3 Réponses :


3
votes

Si votre SGBDR prend en charge SAUF TOUT , vous pouvez simplement l'utiliser et vous avez terminé ( Fiddle ).

SELECT "Articel ID"
FROM   (SELECT "Articel ID",
               ROW_NUMBER()
                 OVER (
                   PARTITION BY "Articel ID"
                   ORDER BY "Articel ID") AS RN
        FROM   TableA
        EXCEPT
        SELECT "Articel ID",
               ROW_NUMBER()
                 OVER (
                   PARTITION BY "Articel ID"
                   ORDER BY "Articel ID") AS RN
        FROM   TableB) T 

Sinon, vous pouvez appliquer un ROW_NUMBER pour numéroter les lignes puis utiliser EXCEPT si disponible (ou tout autre moyen de faire une anti-jointure s'il n'est pas disponible) - db fiddle

SELECT "Articel ID"
FROM   TableA
EXCEPT ALL
SELECT "Articel ID"
FROM   TableB


2 commentaires

Ça marche! Mais maintenant j'ai le problème, que j'ai besoin de 3 autres lignes de la table A. Je pensais que ce serait facile, mais SAUF ne me permet pas d'ajouter une autre ligne.


@maxu - trois autres colonnes pas lignes vraisemblablement. Vous devez cependant expliquer à partir de quelle ligne les valeurs de colonne sont sélectionnées. Il est probablement préférable de le faire en tant que nouvelle question au fur et à mesure de la réponse à votre question initiale



1
votes

Cela devrait fonctionner dans POSTGRES sur la base que vous auriez besoin de quatre 2 dans A et deux 2 dans B pour donner deux 2 dans votre sortie:

SELECT
  ArticleID
FROM (
  SELECT
    TableA.ArticleID,
    ROW_NUMBER() OVER (PARTITION BY TableA.ArticleID) rowNo,
    COALESCE(t2.cnt, 0) rowsToAccept
  FROM
    TableA
  LEFT JOIN (
    SELECT
      ArticleID,
      COUNT(ArticleID) cnt 
    FROM
      TableB
    GROUP BY
      ArticleID
  ) t2
  ON TableA.ArticleID = t2.ArticleID
) t3
WHERE rowNo > rowsToAccept


1 commentaires

Postgres propose un moyen beaucoup plus simple de le faire - comme dans le premier exemple de ma réponse



0
votes

Edit: Échangé dans une solution plus efficace, étant donné que vous avez une colonne unique dans vos deux tableaux.

J'ai pensé que c'était un problème amusant, voici ma solution rapide qui pourrait inspirer.

SELECT
  TableA.ArticelID,
  COUNT(DISTINCT TableA.ID) - COUNT(DISTINCT TableB.ID) As tblDiff
FROM TableA
LEFT JOIN TableB ON TableA.ArticelID = TableB.ArticelID
GROUP BY TableA.ArticelID
HAVING tblDiff <> 0

Il vous indiquera également la différence entre les deux, c'est-à-dire combien sont manquants de l'un ou de l'autre. Idk sur votre volume de données, donc je n'ai pas vraiment réfléchi à l'efficacité.


0 commentaires