2010-05-04 4 views
0

Tout d'abord désolé de ne pas pouvoir trouver un titre plus descriptif.SQL - Comptage des valeurs de Field-B pour chaque valeur de Field-A

Ce que je veux faire est la suivante en utilisant uniquement SQL:

J'ai quelques listes de chaînes, list1, list2 et liste3.

J'ai un jeu de données qui contient deux colonnes intéressantes, A et B. La colonne A contient un TransactionID et la colonne B contient un ItemID.

Naturellement, il peut y avoir plusieurs lignes partageant les mêmes TransactionID.

J'ai besoin pour attraper les transactions qui ont au moins un ItemID dans chaque liste (list1 ET liste2 ET liste3).

J'ai aussi besoin de compter le nombre de fois que cela arrive pour chaque transaction. [EDIT] C'est-à-dire, compte combien de jeux complets d'ID article pour chaque TransactionID "," Ensemble complet "étant un élément de la liste1 avec n'importe quel élément de la liste2 avec un élément de la liste3

J'espère que est logique assez, peut-être que je serai en mesure d'expliquer mieux avec une tête claire.

Merci à l'avance

+0

Avez-vous également une sorte de clé primaire ou une contrainte unique sur une ou plusieurs colonnes de votre tableau? Ou peut-il y avoir des lignes dupliquées complètement identiques? –

+1

Quelle base de données? Serveur SQL? MySQL? –

+1

Les tables list1, list2 et list3 sont-elles composées d'une chaîne par ligne? Sinon, que voulez-vous dire par "listes de chaînes"? Aussi, je ne comprends pas "J'ai aussi besoin de compter combien de fois cela arrive pour chaque transaction".Comptez combien de fois ce qui se passe pour chaque transaction? –

Répondre

0

En MySQL si vous h ave les listes suivantes:

list1 = ('1', '3') 
list2 = ('2', '3') 
list3 = ('3', '5') 

alors vous pouvez faire ceci:

SELECT 
    TransactionID, 
    SUM(ItemID IN ('1', '3')) AS list1_count, 
    SUM(ItemID IN ('2', '3')) AS list2_count, 
    SUM(ItemID IN ('3', '5')) AS list3_count 
FROM table1 
GROUP BY TransactionID 
HAVING list1_count > 0 AND list2_count > 0 AND list3_count > 0 

Résultat:

TransactionId list1_count list2_count list3_count 
1    3   2   1 
3    2   2   1 

données de test:

CREATE TABLE table1 (ID INT NOT NULL, TransactionID INT NOT NULL, ItemID INT NOT NULL); 
INSERT INTO table1 (ID, TransactionID, ItemID) VALUES 
(1, 1, 1), 
(2, 1, 2), 
(3, 1, 3), 
(4, 1, 4), 
(5, 1, 1), 
(6, 2, 1), 
(7, 2, 2), 
(8, 2, 1), 
(9, 2, 4), 
(10, 3, 3), 
(11, 3, 2), 
(12, 3, 1); 
0

Selon votre dialecte, et à supposer que vos listes d'autres tables ...

SELECT 
    TransactionID, Count1, Count2, Count3 
FROM 
    MyDataSet M 
    JOIN 
    (SELECT COUNT(*), ItemID AS Count1 FROM List1 GROUP BY ItemID) T1 ON T1.ItemID = M.ItemID 
    JOIN 
    (SELECT COUNT(*), ItemID AS Count2 FROM List2 GROUP BY ItemID) T2 ON T2.ItemID = M.ItemID 
    JOIN 
    (SELECT COUNT(*), ItemID AS Count3 FROM List3 GROUP BY ItemID) T3 ON T3.ItemID = M.ItemID 
0

Si list1, list2, et list3 sont des énumérations réellement connues, vous pourriez aller avec:

SELECT TransactionID, COUNT(*) 
FROM MyTable 
WHERE ItemID IN (list1) AND ItemID IN (list2) AND ItemID IN (list3) 
GROUP BY TransactionID 

Si vous avez beaucoup de listes, vous pouvez générer le code SQL dans un programme. Cependant, il devrait encore fonctionner assez bien, même pour beaucoup de listes. Placez les listes dans lesquelles vous vous attendez à avoir le moins de correspondances en premier, de sorte que vous arrêtiez d'évaluer le prédicat dès que possible.

Si vos listes sont dans une autre table, peut-être un tas de tuples de la forme (list_id, item_id), c'est un problème plus délicat. J'aimerais en savoir plus avant d'essayer de trouver une requête pour cela.

Questions connexes