2 votes

Requête SQL qui trouve un identifiant qui n'est pas associé à un autre identifiant

Je suis actuellement en train d'apprendre les bases de SQL et j'ai un tutoriel de l'école qui se présente comme suit: Tous les magasins (storeid) vendent (productid, storeid) certains produits (productid) Un magasin est considéré comme un monopole si tous les produits qu'ils vendent ne sont pas vendus par un autre magasin. Comment trouver les monopoles? Je pensais sélectionner les storeid de 2 tables identiques, mais je ne suis pas sûr de la façon de continuer à partir de là.

Les tables sont ci-dessous :

Magasin :

+-----------+
|  storeid  |
+-----------+
| --------- |
|     1     |
|     2     |
|     3     |
|     4     |
|     5     |
+-----------+

Produits :

+-------------+
|  productid  |
+-------------+
| ---------   |
|     1       |
|     2       |
|     3       |
|     4       |
|     5       |
|     6       |
+-------------+

Ventes :

+--------------------------+
|   productid | storeid    |
+--------------------------+
| -----------+------------ |
|          1 |          1  |
|          2 |          1  |
|          2 |          2  |
|          3 |          2  |
|          1 |          2  |
|          3 |          3  |
|          2 |          4  |
|          4 |          4  |
|          5 |          5  |
|          6 |          5  |
+--------------------------+

Donc, selon mon décompte, seul le magasin 5 est considéré comme un monopole, car ils vendent des produits qui ne sont pas disponibles dans les autres magasins.

1voto

Tim Biegeleisen Points 53335

Nous pouvons essayer une approche d'auto-jonction combinée avec l'agrégation :

SÉLECTIONNEZ t1.storeid
DE votreTable t1
GAUCHE JOINDRE votreTable t2
    ON t2.productid = t1.productid ET
       t2.store_id <> t1.storeid
GROUPE PAR t1.storeid
AYANT COMPTER(t2.storeid) = 0;

L'approche ici est d'essayer de faire correspondre chaque ligne de Ventes à une autre ligne sous la condition qu'il s'agisse du même produit, mais vendu par un autre magasin. Un magasin correspondant est un magasin pour lequel aucun de ses produits n'est vendu par d'autres magasins, donc le décompte de la seconde colonne de la table jointe devrait être égal à zéro.

0voto

Gordon Linoff Points 213350

Utilisez les fonctions de fenêtrage et l'agrégation:

select s.storeid
from (select s.*,
             count(*) over (partition by productid) as num_stores
      from sells s
     ) s
group by s.storeid
having max(num_stores) = 1;

Cela devrait être beaucoup plus rapide qu'une auto-jointure. C'est également presque une traduction directe de votre question. La sous-requête compte le nombre de magasins où chaque produit est vendu. La requête externe sélectionne les magasins où tous les produits sont vendus dans un magasin.

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