web-dev-qa-db-fra.com

Est-il possible de spécifier la condition dans Count ()?

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.

350
agnieszka

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 ...
606
Guffa

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 ...
200
RedFilter

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 ...
25
Hivenfour

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
20
AdaTheDev

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')
12
Matthew Whited

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 :-)

3
z00l

Voulez-vous dire juste ceci:

SELECT Count(*) FROM YourTable WHERE Position = 'Manager'

Si oui, alors ça marche!

2
Dana
SELECT COUNT(*) FROM bla WHERE Position = 'Manager'
0
Peter

Je pense que vous pouvez utiliser une simple clause WHERE pour sélectionner uniquement le compte de certains enregistrements.

0
NawaMan

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
0
user3029478

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)

0
Thomas Decaux