web-dev-qa-db-fra.com

Diviser le nombre par nombre (*) dans SQL Server

Voici ma requête:

SELECT 
    COUNT(*) AS total,
    COUNT(CASE WHEN t.id IS NULL THEN 1 END) AS nb_null,
    COUNT(CASE WHEN t.id IS NOT NULL THEN 1 END) AS nb_not_null
FROM
    table t

Est-il possible de diviser un champ par un alias? :

SELECT 
    COUNT(*) AS total,
    COUNT(CASE WHEN t.id IS NULL THEN 1 END) / total AS nb_null,
    COUNT(CASE WHEN t.id IS NOT NULL THEN 1 END) AS nb_not_null
FROM
    table t

Cela ne fonctionne pas pour moi dans SQL Server, j'aimerais savoir s'il existe un moyen de le faire? Merci

4
Vincent Ducroquet

Au lieu de 

COUNT(CASE WHEN t.id is null THEN 1 END)/Count(*) 

Vous pouvez utiliser

AVG(CASE WHEN t.id is null THEN 1.0 ELSE 0 END)
13
Martin Smith

Malheureusement, vous ne pouvez pas utiliser une variable alias comme celle-ci dans Sql Server; vous devez répéter l'expression. Vous pouvez (comme vous l'avez déjà constaté et que d'autres l'ont posté) utiliser une sous-requête/cte/join etc. pour renvoyer une colonne avec cet alias et l'utiliser comme cela, mais il s'agit alors du nom de la colonne/expression et non d'un alias. 

SELECT Count(*) as total,
count(CASE WHEN t.id is null THEN 1 END)/(Count(*)+.0)  as nb_null,
COUNT(CASE WHEN t.id is not null THEN 1 END) as nb_not_null
from table t

Ajoutez également +.0 à l’un ou l’autre des côtés de votre équation de division pour éviter une division entière (renvoie 0 au lieu de 0.dddd pour cent).

2
SqlZim

Ok je l'ai trouvé moi-même:

SELECT nb_null/total from(
   SELECT Count(*) as total,
   COUNT(CASE WHEN t.id is null THEN 1 END) as nb_null,
   COUNT(CASE WHEN t.id is not null THEN 1 END) as nb_not_null
   from table t
) as req
1
Vincent Ducroquet

J'avais besoin de résoudre un problème similaire avec un nombre arbitraire de fonctionnalités (pas seulement null contre non-null), et je voulais également les convertir en pourcentages. Cela peut être utile pour vous ou pour quelqu'un d'autre avec une question similaire:

WITH counts AS 
  (SELECT [feature], 
  COUNT(*) AS cnt
  FROM [your_table]
  GROUP BY [feature])
SELECT [feature], CAST(100 * num AS DOUBLE) / (SELECT SUM(num) FROM counts) 
  AS pct
FROM counts
ORDER BY pct DESC
1
mr_snuffles

J'écrirais ceci comme:

select Count(*) as total,
       avg(case when t.id is null then 1.0 else 0 end) as nb_null,
       count(t.id) as nb_not_null
from table t;

La définition de COUNT(<col>) est qu’elle compte des valeurs non NULL; vous pourriez bien utiliser la fonction intégrée.

Cependant, pourquoi une colonne appelée id pourrait être NULL me dépasse. Il devrait être déclaré NOT NULL.

1
Gordon Linoff