Est-il possible de spécifier une condition dans Count()
? Je voudrais ne compter que les lignes qui ont, par exemple, "Manager" dans la colonne Position.
Je veux le faire dans l'instruction count sans utiliser WHERE
; Je pose la question à ce sujet parce que je dois compter les gestionnaires et les autres dans la même SELECT
(quelque chose comme Count(Position = Manager), Count(Position = Other))
donc WHERE
ne me sert à rien dans cet exemple.
Si vous ne pouvez pas limiter la requête elle-même avec une clause where
, vous pouvez utiliser le fait que l'agrégat count
ne compte que les valeurs non nulles:
select count(case Position when 'Manager' then 1 else null end)
from ...
Vous pouvez également utiliser l'agrégat sum
de la même manière:
select sum(case Position when 'Manager' then 1 else 0 end)
from ...
En supposant que vous ne souhaitiez pas restreindre les lignes renvoyées car vous agrégiez également d'autres valeurs, vous pouvez le faire comme suit:
select count(case when Position = 'Manager' then 1 else null end) as ManagerCount
from ...
Supposons que, dans la même colonne, vous ayez les valeurs de gestionnaire, de superviseur et de chef d'équipe, vous pouvez obtenir le nombre de chacun comme ceci:
select count(case when Position = 'Manager' then 1 else null end) as ManagerCount,
count(case when Position = 'Supervisor' then 1 else null end) as SupervisorCount,
count(case when Position = 'Team Lead' then 1 else null end) as TeamLeadCount,
from ...
La réponse de @Guffa est excellente, il suffit de souligner que peut-être est plus propre avec une déclaration IF
select count(IF(Position = 'Manager', 1, NULL)) as ManagerCount
from ...
Cela dépend de ce que vous voulez dire, mais l’autre interprétation de la signification est celle où vous voulez compter les lignes avec une certaine valeur, mais ne voulez pas restreindre la SELECT
à JUST ces lignes ...
Vous le feriez en utilisant SUM()
avec une clause dans, comme ceci au lieu d'utiliser COUNT()
: par ex.
SELECT SUM(CASE WHEN Position = 'Manager' THEN 1 ELSE 0 END) AS ManagerCount,
SUM(CASE WHEN Position = 'CEO' THEN 1 ELSE 0 END) AS CEOCount
FROM SomeTable
Vous pouvez également utiliser le mot-clé Pivot si vous utilisez SQL 2005 ou une version ultérieure.
plus d'infos et de Technet
SELECT *
FROM @Users
PIVOT (
COUNT(Position)
FOR Position
IN (Manager, CEO, Employee)
) as p
Jeu de données de test
DECLARE @Users TABLE (Position VARCHAR(10))
INSERT INTO @Users (Position) VALUES('Manager')
INSERT INTO @Users (Position) VALUES('Manager')
INSERT INTO @Users (Position) VALUES('Manager')
INSERT INTO @Users (Position) VALUES('CEO')
INSERT INTO @Users (Position) VALUES('Employee')
INSERT INTO @Users (Position) VALUES('Employee')
INSERT INTO @Users (Position) VALUES('Employee')
INSERT INTO @Users (Position) VALUES('Employee')
INSERT INTO @Users (Position) VALUES('Employee')
INSERT INTO @Users (Position) VALUES('Employee')
Je sais que c’est vraiment vieux, mais j’aime l’astuce NULLIF
pour de tels scénarios, et j’ai trouvé aucun inconvénient pour l’instant. Il suffit de voir mon exemple de copie et de copie, ce qui n’est pas très pratique, mais montre comment l’utiliser.
NULLIF
pourrait vous donner un léger impact négatif sur les performances, mais je suppose que cela devrait quand même être plus rapide que les sous-requêtes.
DECLARE @tbl TABLE ( id [int] NOT NULL, field [varchar](50) NOT NULL)
INSERT INTO @tbl (id, field)
SELECT 1, 'Manager'
UNION SELECT 2, 'Manager'
UNION SELECT 3, 'Customer'
UNION SELECT 4, 'Boss'
UNION SELECT 5, 'Intern'
UNION SELECT 6, 'Customer'
UNION SELECT 7, 'Customer'
UNION SELECT 8, 'Wife'
UNION SELECT 9, 'Son'
SELECT * FROM @tbl
SELECT
COUNT(1) AS [total]
,COUNT(1) - COUNT(NULLIF([field], 'Manager')) AS [Managers]
,COUNT(NULLIF([field], 'Manager')) AS [NotManagers]
,(COUNT(1) - COUNT(NULLIF([field], 'Wife'))) + (COUNT(1) - COUNT(NULLIF([field], 'Son'))) AS [Family]
FROM @tbl
Commentaires appréciés :-)
Voulez-vous dire juste ceci:
SELECT Count(*) FROM YourTable WHERE Position = 'Manager'
Si oui, alors ça marche!
SELECT COUNT(*) FROM bla WHERE Position = 'Manager'
Je pense que vous pouvez utiliser une simple clause WHERE pour sélectionner uniquement le compte de certains enregistrements.
Voici ce que j'ai fait pour obtenir un ensemble de données comprenant à la fois le total et le nombre répondant aux critères, dans chaque conteneur d'expédition. Cela me permet de répondre à la question "Combien de conteneurs d'expédition ont plus de X% d'articles de taille supérieure à 51"
select
Schedule,
PackageNum,
COUNT (UniqueID) as Total,
SUM (
case
when
Size > 51
then
1
else
0
end
) as NumOverSize
from
Inventory
where
customer like '%PEPSI%'
group by
Schedule, PackageNum
Remarquez avec PrestoDB SQL (de Facebook), il existe un raccourci:
https://prestodb.io/docs/current/functions/aggregate.html
count_if (x) → bigint
Renvoie le nombre de valeurs d'entrée TRUE. Cette fonction est équivalente à compter (CASE WHEN x THEN 1 END)