2009-05-08 2 views
0

Je souhaite créer une requête sql qui indique le pourcentage de résultats dans une plage particulière. par exempleComment créer une requête SQL qui regroupe des plages de valeurs

20% des valeurs comprises entre 10 à 20

40% des valeurs comprises entre 20 à 32,5

serveur - MSSQL

+0

que visez-vous? – curtisk

+0

Apparemment SQL Server, si vous considérez les balises. –

+0

fyi: près de 5 000 questions marquées 'sqlserver' contre seulement 56 'mssql'. Quel tag pensez-vous que la communauté a décidé d'utiliser? –

Répondre

2
SELECT B.Description, Total = COUNT(*)/CONVERT(money, (SELECT COUNT(*) FROM Target T2)) 
FROM Target T 
JOIN (
    SELECT Description = '0 to 10', LBound = 0, UBound = 10 
    UNION ALL 
    SELECT Description = '10 to 20', LBound = 10, UBound = 20 
) B ON T.Value >= LBound AND T.Value < B.UBound 
GROUP BY B.Description 
2
GROUP BY CASE 
     WHEN VALUE >= 10 AND VALUE <= 20 THEN '20%' 
     WHEN VALUE > 20 AND VALUE <= 32.5 THEN '40%' ELSE '0' END 

Vous devez couvrir tous possible valeurs, d'où l'ELSE 0. Vous voudrez probablement faire quelque chose d'un peu différent là-bas, mais il devrait vous donner un début.


Basé sur le commentaire de Joel Gauvreau:

SUM(CASE WHEN VALUE >=10 AND VALUE <= 20 THEN 1.0 ELSE 0.0 END)/COUNT(*), 
SUM(CASE WHEN VALUE > 20 AND VALUE <= 32.5 THEN 1.0 ELSE 0.0 END)/COUNT(*) 

Ou à la fin de la requête utilisez l'instruction COMPUTE.

+0

Je pense qu'il voulait dire la distribution des valeurs par gamme. 200 enregistrements où la valeur est comprise entre 10 et 20 donnerait quel pourcentage du nombre total d'enregistrements ... –

+0

Ah, merci. Mise à jour ma réponse –

+0

+1 meilleure idée, mais nécessite une distribution d'entier à float, et un extra) pour la somme sur la deuxième ligne – Andomar

2

Cela vous obtenir le nombre par gamme, vous pouvez facilement déterminer le pourcentage à partir de là:

declare @ranges table (beginInclusive float, endExclusive float) 
insert @ranges (beginInclusive, endExclusive) 
    select 10, 20 
    union all select 20, 32.5 

select 
    r.beginInclusive, 
    r.endExclusive, 
    count(*) 
from t join @ranges on t.RangedValue >= r.beginInclusive and t.RangedValue < r.endExclusive 
group by 
    r.beginInclusive, 
    r.endExclusive  
+0

C'est une approche intéressante ... au lieu d'une table var, on pourrait aussi créer une table statique. Pourquoi: pour des choses comme les préférences de l'utilisateur qui persisteraient entre les sessions. – nykash

0

Je généralement utiliser un sous-requête et obtenir rangecounts et rejoindre dans le total pour obtenir le pourcentage. Quelque chose comme:

SELECT 
    RangeCount/CNT as Percentage, 
    Range 
FROM 
(
SELECT 
    Count(*) AS CNT 
FROM 
    SomeTable 
) AS Total 
LEFT JOIN 
(
SELECT 
    CASE Val <= 10 then 
     '0 up to 10' 
    ELSE 
     CASE when Val <= 20 
     '11 to 20' 
     ELSE 
     '> 20' 
     END 
    END 
    END AS Range, 
    COUNT(*) AS RangeCount 
FROM 
    SomeTable 
GROUP BY 
    Range 
) AS RangeTotals 
0
Declare @1 as int 
Declare @2 as int 
Declare @TotalRows as int 

set @1 = (Select COUNT(id) FROM dbo.Table_1 WHERE id >= 10 and id <= 20) 
set @2 = (Select COUNT(id) FROM dbo.Table_1 WHERE id > 20 AND id <= 32.5); 
set @TotalRows = (Select Count(id) from dbo.Table_1); 

SELECT CAST(((@1 * 100)/@TotalRows) as nvarchar(32)) + '%', CAST(((@2 * 100)/@TotalRows) as nvarchar(32)) + '%'; 

peu compliqué, mais qui fonctionne ... je suppose ...

dbo.Table_1 seulement a 1 colonne, 'id' et il est type int.

0

Si c'est quelque chose que vous ferez régulièrement, vous pouvez créer une table avec les plages et ce qui constitue ces plages. Si ce n'est pas le cas, vous pouvez les configurer dans une table table ou une table temporaire et vous joindre à cela. C'est essentiellement la solution de JohnOpincar, mais avec une table au lieu d'une sous-requête.

En outre, dans votre exemple, vous indiquez "10 à 20" et "20 à 32,5". Où une ligne est-elle comptée si c'est exactement 20? Vous devriez probablement vous assurer que vos exigences sont claires sur ce point avant de livrer la solution finale.

0

La réponse de Joel me semble la meilleure. Publier pour expliquer la requête, et parce que la réponse a une somme/un nombre entier de division qui retournera 1 ou 0 au lieu d'un pourcentage.

Pour le 20 -> 32,5 gamme:

select CAST(SUM(
    CASE WHEN 20 < field AND field <= 32.5 THEN 1 ELSE 0 END 
    ) as float)/COUNT(*) * 100.0 
from table 

Le cas retourne 1 lorsque la valeur est à portée. Comme il n'y a pas de clause group by, la somme ajoute le résultat du cas pour chaque ligne de la table. Convertir en float, diviser par le nombre de lignes = count (*), et vous obtenez le pourcentage.

Vous pouvez également écrire comme:

select SUM(
    CASE WHEN 20 < field AND field <= 32.5 THEN 1.0 ELSE 0.0 END 
    )/COUNT(*) * 100 
from table 

le cas ici se traduira par un flotteur 1.0 au lieu de l'entier 1.

Questions connexes