2009-12-16 5 views
1

Ok cette une est vraiment délicate: Dproblème avec requête SQL distincte avancée

j'ai ce tableau

bills_products: 
- bill_id - product_id - action - 
| 1 |  4  | add | 
| 1 |  5  | add | 
| 2 |  4  | remove | 
| 2 |  1  | add | 
| 3 |  4  | add | 

comme vous pouvez le voir produit avec l'ID 4 a été ajouté au projet de loi 1 ensuite éliminé facture 2 et ajouté à nouveau dans le projet de loi 3

Toutes les factures appartiennent à un groupe de facturation. Mais pour la simplicité, supposons que toutes les factures sont dans le même groupe.

Maintenant, j'ai besoin d'une requête SQL qui montre tous les produits qui sont actuellement ajoutés à ce groupe.

Dans cet exemple qui serait 5, 1 et 4. Si nous retirer le projet de loi avec id 3 qui serait 5 et 1

J'ai essayé de le faire avec DISTINCT mais pas assez puissant ou peut-être que je le fais mal.

+0

mais l'ID de produit 4 est toujours ajouté à la facture 1, donc ne serait-il pas encore là? – GSto

+0

Oui, c'est le problème! – antpaw

Répondre

3

Cela semble fonctionner dans SQL Server au moins:

select product_id 
from (
      select product_id, 
        sum((case when action='add' then 1 else -1 end)) as number 
      from bills_products 
      group by product_id 
     ) as counts 
where number > 0 
+0

En supposant que vous avez déjà protégé plusieurs événements de suppression, par exemple, "ajouter, supprimer, supprimer, ajouter". –

+0

Il est vrai que j'ai supposé qu'ils ne pouvaient pas supprimer des choses qui avaient déjà été supprimées. – Rich

+0

Pourquoi? Cela devrait même fonctionner avec plusieurs suppressions ou est-ce que quelque chose me manque? –

0
SELECT DISTINCT product_id FROM bills_products WHERE action = 'add'; 
+0

cela ne fonctionnera pas, si vous supprimez le projet de loi 3, il vous montrera le product_id 4, mais il a été retiré dans le projet de loi 2. – antpaw

+0

ah, j'ai mal compris la question. – GSto

0

gsto avait presque, mais vous devez ORDER BY bill_id DESC pour vous assurer d'obtenir les derniers enregistrements.

SELECT DISTINCT product_id FROM bills_products 
WHERE action = 'add' 
ORDER BY bill_id DESC; 

(PS je pense que la plupart des gens diraient que c'est une meilleure pratique d'avoir une colonne d'horodatage sur les tables comme celui-ci où vous devez être en mesure de savoir ce que la « nouvelle » ligne est. Vous ne pouvez pas toujours compter sur les identifiants uniquement ascendants.)