2009-05-12 2 views
4

J'ai une table appelée Person qui contient un champ appelé PersonAge. Je dois regrouper les âges par tranches d'âge, c'est-à-dire '12 et moins ', '13 -17', '18 -25 ', '25 et plus' et renvoyer ce résultat en utilisant une procédure stockée.SQL Création d'un proc stocké pour le retour des tranches d'âge

Idéalement j'ai besoin de 2 champs retournés, 'âge Band', 'Total' comme si

Age band   Total 
12 and under  5 
13 - 17   8 
18 - 25   7 
25 and over  10 
+0

@Mich, votre chevauchement de bande d'âge "18-25" et "25 et plus". –

+0

@ Lieven Bien repéré Lieven, c'était une faute de frappe dans la question car il était tard dans la nuit (c'est mon excuse!), Je peux vous assurer que ce n'est pas dans le code de production ... – Mitch

Répondre

13

Créer une table contenant vos groupes:

CREATE TABLE agebands 
(
    id INT NOT NULL PRIMARY KEY, 
    lower_bound INT NOT NULL, 
    upper_bound INT NOT NULL 
) 
CREATE INDEX IDX_agebands_bounds ON (lower_bound, upper_bound) 

remplir ensuite avec vos données:

INSERT INTO agebands VALUES (1, 0, 12) 
INSERT INTO agebands VALUES (2, 13, 17) 
INSERT INTO agebands VALUES (3, 18, 24) 
INSERT INTO agebands VALUES (4, 25, 199) 

ensuite se joindre à lui:

SELECT 
    lower_bound, upper_bound, 
    COUNT(*) AS number_of_people 
FROM 
    persons 
    INNER JOIN agebands 
     ON person_age BETWEEN lower_bound AND upper_bound 
GROUP BY 
    lower_bound, upper_bound 
ORDER BY 
    lower_bound 

Cela permet flexibilité dans l'ajustement de la bande s. Bien sûr, l'autre réponse ici en utilisant UNION est également utilisable, ce qui est plus approprié si vous ne pouvez pas/ne voulez pas ajouter une autre table à votre base de données.

+0

+1 pour la flexibilité – Scoregraphic

+0

+1 Neat, bien que pour cet exemple trivial je soutiendrais que l'union est plus facile de maintenir alors la table supplémentaire. Après un an, personne ne se souvient que tout ce qu'ils ont à faire est d'ajouter, supprimer ou modifier un enregistrement dans une table sans lire la procédure source de toute façon. –

+0

+1 Ceci est plus efficace et maintenable que la réponse basée sur l'union –

4

Une UNION simple devrait suffire.

SELECT [Ageband] = '12 and under', COUNT(*) 
FROM dbo.Person 
WHERE PersonAge <= 12 
UNION ALL SELECT '13-17', COUNT(*) 
FROM dbo.Person 
WHERE PersonAge BETWEEN 13 AND 17 
UNION ALL SELECT '18-25', COUNT(*) 
FROM dbo.Person 
WHERE PersonAge BETWEEN 18 AND 25 
UNION ALL SELECT '26 and over', COUNT(*) 
FROM dbo.Person 
WHERE PersonAge >= 26 
2

Ce qui suit devrait donner:

select count(*), person_age 
from (
    select (case 
       when age between 0 and 12 then '12 and under' 
       when age between 13 and 17 then '13-17' 
       when age between 18 and 25 then '18-15' 
       else 'Above 25' 
      end) as 'person_age' 
    from person) 
group by person_age 
+0

à son état actuel cela ne compile pas, mais il pourrait être fait pour travailler ... –

0
declare @tempT table(age int) 
declare @temp2 table(age2 varchar(15)) 

insert into @tempT(age) values(1) 
insert into @tempT(age) values(2) 
insert into @tempT(age) values(3) 
insert into @tempT(age) values(4) 
insert into @tempT(age) values(5) 
insert into @tempT(age) values(6) 
insert into @tempT(age) values(7) 
insert into @tempT(age) values(8) 
insert into @tempT(age) values(9) 
insert into @tempT(age) values(10) 
insert into @tempT(age) values(11) 

insert into @Temp2 
select case 
when age < 3 then '<3' 
when age >= 3 and age < 5 then '>= 3 and < 5' 
when age >= 5 then '>=5' 
end 
from @tempT 

select count(*), age2 from @Temp2 
GROUP BY age2 
1

Dans SQL vous ne pouvez pas le groupe par un alias de colonne. Vous devez répéter l'instruction de cas comme ceci.

select count(*), 
case 
    when aged between 0 and 12 then '12 and under' 
    when aged between 13 and 17 then '13-17' 
    when aged between 18 and 25 then '18-15' 
    else 'Above 25' end 
from person 
group by 
case 
    when aged between 0 and 12 then '12 and under' 
    when aged between 13 and 17 then '13-17' 
    when aged between 18 and 25 then '18-15' 
    else 'Above 25' 
end 
Questions connexes