Fonction d'agrégation dans SQL WHERE-Clause
Dans un test à l'université, il y avait une question; est-il possible d'utiliser une fonction d'agrégation dans le SQL WHERE
clause.
J'ai toujours pensé que ce n'était pas possible et je ne trouve pas non plus d'exemple sur la façon dont cela serait possible. Mais ma réponse a été marquée faux et maintenant, je veux savoir dans quels cas il est possible d'utiliser une fonction d'agrégation dans le WHERE
. Aussi, si ce n'est pas possible, il serait bon d'obtenir un lien vers la spécification où il est décrit.
6 réponses
Vous n'avez pas mentionné le SGBD. En supposant que vous utilisez MS SQL-Server, j'ai trouvé un message D'erreur T-SQL qui est explicite:
" un agrégat peut ne pas apparaître dans Clause WHERE sauf si elle est dans un sous-requête contenue dans une clause HAVING ou une liste de sélection, et la colonne agrégé est une référence externe "
Http://www.sql-server-performance.com/
Et un exemple qu'il est possible dans une sous-requête.
Tout afficher clients et plus petite commande pour ceux qui ont 5 commandes ou plus (et NULL pour les autres):
SELECT a.lastname
, a.firstname
, ( SELECT MIN( o.amount )
FROM orders o
WHERE a.customerid = o.customerid
AND COUNT( a.customerid ) >= 5
)
AS smallestOrderAmount
FROM account a
GROUP BY a.customerid
, a.lastname
, a.firstname ;
Mise à jour.
Ce qui précède s'exécute à la fois dans SQL-Server et MySQL mais il ne renvoie pas le résultat attendu. Le suivant est plus proche. Je suppose que cela a à voir avec le fait que le Champ customerid
, groupé par et utilisé dans la jointure query-subquery est dans le premier cas la clé primaire de la table externe et dans le second cas ce n'est pas le cas.
Afficher tous les identifiants clients et le nombre de commandes pour ceux qui avoir 5 commandes ou plus (et NULL pour les autres):
SELECT o.customerid
, ( SELECT COUNT( o.customerid )
FROM account a
WHERE a.customerid = o.customerid
AND COUNT( o.customerid ) >= 5
)
AS cnt
FROM orders o
GROUP BY o.customerid ;
Avoir est comme WHERE avec des fonctions d'agrégation, ou vous pouvez utiliser une sous-requête.
select EmployeeId, sum(amount)
from Sales
group by Employee
having sum(amount) > 20000
Ou
select EmployeeId, sum(amount)
from Sales
group by Employee
where EmployeeId in (
select max(EmployeeId) from Employees)
Vous ne pouvez pas utiliser un agrégat directement dans une clause WHERE; c'est à quoi servent les clauses HAVING.
Vous pouvez utiliser une sous-requête qui contient un agrégat dans la clause where.
Requête mise à jour:
select id from t where id < (select max(id) from t);
Il sélectionnera tout sauf la dernière ligne de la table t.
SELECT COUNT( * )
FROM agents
HAVING COUNT(*)>3;
Voir plus ci-dessous Lien:
Http://www.w3resource.com/sql/aggregate-functions/count-having.php#sthash.90csRM4I.dpuf][1] appelez - moi si une question:85110 51548
Http://www.w3resource.com/sql/aggregate-functions/count-having.php
Une autre solution consiste à déplacer la fonction agrégée vers la fonction définie par L'utilisateur scalaire
Créez Votre Fonction:
CREATE FUNCTION getTotalSalesByProduct(@ProductName VARCHAR(500))
RETURNS INT
AS
BEGIN
DECLARE @TotalAmount INT
SET @TotalAmount = (select SUM(SaleAmount) FROM Sales where Product=@ProductName)
RETURN @TotalAmount
END
Utilisation de la Fonction dans la Clause where
SELECT ProductName, SUM(SaleAmount) AS TotalSales
FROM Sales
WHERE dbo.getTotalSalesByProduct(ProductName) > 1000
GROUP BY Product
Références:
L'espoir aide quelqu'un.