2010-07-02 7 views
2

J'ai trois tables, nous les appellerons table1, table2 et table3. Disons que chaque table a une colonne d'identifiant et une colonne de date. Qu'est-ce que je voudrais faire est de pouvoir compter le nombre de lignes avec un ID utilisateur spécifique dans table1, et le somme avec le nombre de lignes avec cet ID utilisateur dans les tables 2 et 3.Requête SQL compliquée - Trouver un ensemble de quelque chose, le compter, puis trouver un sous-ensemble du premier ensemble, et compter que

Ensuite, j'aime prendre cette première requête que j'ai faite qui a toutes les lignes avec l'identifiant de l'utilisateur, et ensuite sortir et compter celles où la colonne de date est supérieure à une certaine date (unix temps).

Tout ce que je voudrais recevoir à la fin est deux choses. Le nombre de lignes dans les tables 1, 2 et 3 qui ont l'ID utilisateur que je cherchais sommés ensemble, et le nombre de lignes dans les tableaux 1, 2 et 3 qui ont l'ID utilisateur que je cherchais tout en étant après un certain date additionnée

Quelle est la manière la plus efficace de le faire?

Merci!

+1

un exemple serait vraiment utile, et pour des questions d'efficacité, sachant la cible db est aussi très utile. – mdma

+0

Le tableau 1 est des chiens, le tableau 2 est des chats, le tableau 3 est des furets. La date est quand ils ont été achetés. Dites que l'identifiant de mon ami Sam est 9. Je veux être en mesure de compter le nombre total d'animaux que mon ami Sam a, IE le nombre de chats avec l'ID utilisateur de 9, le nombre de furets avec ID 9, et le nombre de chiens avec id de 9 sommés ensemble. Ensuite, j'aimerais pouvoir compter le nombre d'animaux que mon ami Sam a acheté après le mois de juin de l'année dernière. Je préférerais ne pas avoir à les parcourir toutes les deux fois, puisque tous les animaux que Sam a achetés après juin sont encapsulés dans le nombre d'animaux que Sam possède. – Ethan

Répondre

5
SELECT 
    COUNT(*) AS TotalPets, 
    SUM(CASE WHEN date > somedate THEN 1 ELSE 0 END) AS TotalPetsAfterDate 
FROM 
(
SELECT date FROM dogs WHERE UserId = 9 
UNION ALL 
SELECT date FROM cats WHERE UserId = 9 
UNION ALL 
SELECT date FROM ferrets WHERE UserId = 9 
) Pets 

Ou une alternative à essayer cela peut rendre Imre plus heureux.

SELECT 
    SUM(PetsSubTotal) AS TotalPets, 
    SUM(PetsAfterDateSubTotal) AS TotalPetsAfterDate 
FROM 
(
SELECT COUNT(*) AS PetsSubTotal, SUM(CASE WHEN date > somedate THEN 1 ELSE 0 END) AS PetsAfterDateSubTotal 
FROM dogs 
WHERE UserId = 9 
UNION ALL 
SELECT COUNT(*) AS PetsSubTotal, SUM(CASE WHEN date > somedate THEN 1 ELSE 0 END) AS PetsAfterDateSubTotal 
FROM cats 
WHERE UserId = 9 
UNION ALL 
SELECT COUNT(*) AS PetsSubTotal, SUM(CASE WHEN date > somedate THEN 1 ELSE 0 END) AS PetsAfterDateSubTotal 
FROM ferrets 
WHERE UserId = 9 
) SubTotals 
+1

+1 exactement ce que j'écrivais! – mdma

+0

c'est inefficace car il compose une table temporaire. Cela peut être fait en utilisant simplement count (*) - s qui utilise des métadonnées de table et/ou des index. –

+0

@Imre L - Sur quoi vous basez-vous? Nous ne connaissons même pas le SGBDR cible. –

0

Comme alternative à l'autre réponse (que j'aime aussi) et en supposant que vous avez une table d'ID de l'utilisateur:

Select 
    CustID, Count(Pet_ID) as Total, Sum(In_Range) as AfterDate 
From 
    (Select 
    CustID, Pet_ID, Case When PurDate > somedate Then 1 else 0 End as In_Range 
    From 
    Users 
    Inner Join 
    Pets 
     on Users.CustId = Pets.CustId 
    Where 
    CustId = 9) D 
Group By 
    CustID 
Questions connexes