2012-04-11 2 views
0

Je tente d'obtenir certains enregistrements d'une table en fonction de certains facteurs. L'un des facteurs est simplement avec des champs sur la même table, l'autre est en rejoignant une autre table, je veux comparer le nombre d'enregistrements dans la table jointe à un champ sur la première table. Voici un exemple de code.SQL Sélectionner où ou avoir

select * from tDestinations D 
left join tLiveCalls LC on LC.DestinationID = D.ID 
where D.ConfigurationID = 1486 
AND (D.Active = 1 AND D.AlternateFail > GETDATE()) 
-- Having COUNT(LC.ID) = D.Lines 

maintenant du code ci-dessus je ne peux pas avoir la fonction de comptage dans la clause where, et je ne peux pas avoir un champ dans la clause having sans qu'il soit dans une fonction.

Je manque probablement quelque chose de très simple ici. Mais je ne peux pas comprendre.

Toute aide est appréciée.

EDIT: Je m'excuse d'avoir expliqué la structure des tables, les destinations sont des enregistrements uniques, que la table LiveCalls peut contenir plusieurs enregistrements en fonction de l'ID de destination (clé étrangère).

Merci beaucoup pour votre aide. Mon dernier code:

select D.ID, D.Description, D.Lines, D.Active, D.AlternateFail, D.ConfigurationID, COUNT(LC.ID) AS LiveCalls from tDestinations D 
left join tLiveCalls LC on LC.DestinationID = D.ID 
where D.ConfigurationID = @ConfigurationID 
AND (D.Active = 1 AND D.AlternateFail > GETDATE()) 
GROUP BY D.ID, D.Description, D.Lines, D.Active, D.AlternateFail, D.ConfigurationID 
HAVING COUNT(LC.ID) <= D.Lines 
+0

'WHERE' traite les lignes, 'HAVING' traite les groupes, voir ceci: http://stackoverflow.com/a/1131076/65223 Les fonctions d'agrégation fonctionnent sur les groupes. Par conséquent, ils doivent être dans le «HAVING» et non le «WHERE» –

Répondre

2

La simple chose qui vous manque est the GROUP BY statement.

Comme JNK mentionné dans les commentaires ci-dessous, vous ne pouvez pas utiliser une fonction d'agrégation (comme COUNT, AVG, SUM, MIN) si vous ne disposez pas d'une clause GROUP BY, à moins que votre déclaration SELECT que des références de valeurs littérales (et non noms de colonne).

Votre code devrait probablement être quelque chose comme:

SELECT <someFields> 
FROM tDestinations D 
LEFT JOIN tLiveCalls LC on LC.DestinationID = D.ID 
WHERE D.ConfigurationID = 1486 
AND (D.Active = 1 AND D.AlternateFail > GETDATE()) 
GROUP BY <someFields> 
HAVING COUNT(LC.ID) = D.Lines 

Notez que vous devez spécifier les champs sélectionnés explicitement, dans les deux SELECT et GROUP BY déclarations (pas * autorisés).

+0

Voir [docs] (http://msdn.microsoft.com/en-us/library/ms180199 (v = sql.90). aspx): "group by" n'est pas nécessaire. –

+2

ce serait upvote-able si vous l'avez expliqué un peu plus loin pour l'OP – JNK

+0

@MattFenwick - C'est si vous voulez utiliser une fonction d'agrégat! – JNK

1

vous ne pouvez utiliser qu'avec des agrégations. En fait, avoir la "clause where" pour l'agrégation, MAIS vous pouvez toujours avoir un où sur les colonnes que vous n'êtes pas en train d'agréger.

Par exemple:

SELECT TABLE_TYPE, COUNT(*) 
FROM INFORMATION_SCHEMA.TABLES 
where TABLE_TYPE='VIEW' 
group by TABLE_TYPE 
having COUNT(*)>1 

Dans votre cas, vous devez utiliser le nombre havving (*) = 1 , je pense que votre question serait quelque chose comme ceci:

select YOUR_COLUMN 
from tDestinations D 
left join tLiveCalls LC on LC.DestinationID = D.ID 
where D.ConfigurationID = 1486 AND (D.Active = 1 AND D.AlternateFail > GETDATE()) 
group by YOUR_COLUMN 
Having COUNT(LC.ID) = value