我得到了以下Patients
表。
HospitalId INT,
GenderId BIT,
Age TINYINT,
DiseaseId SMALLINT
GenderId
= 0是男性
GenderId
= 1是女性
HospitalA的HospitalId
0
HospitalB有HospitalId
1
这是我想要产生的输出:
DiseaseId | HospitalA_Male_18-30 | HospitalA_Male_31-40 |
---------------------------------------------------------
0 | (count here) | (count here) |
1 | (count here) | (count here) |
2 | (count here) | (count here) |
3 | (count here) | (count here) |
(专栏继续)
HospitalA_Female_18-30 | HospitalA_Female_31-40 |
-------------------------------------------------
(count here) | (count here) |
(count here) | (count here) |
(count here) | (count here) |
(count here) | (count here) |
(专栏继续)
HospitalB_Male_18-30 | HospitalB_Male_31-40 |
---------------------------------------------
(count here) | (count here) |
(count here) | (count here) |
(count here) | (count here) |
(count here) | (count here) |
(专栏继续)
HospitalB_Female_18-30 | HospitalB_Female_31-40 |
-------------------------------------------------
(count here) | (count here) |
(count here) | (count here) |
(count here) | (count here) |
(count here) | (count here) |
(结果集中的9列)
因此,您可以看到我实际上需要计算每种疾病,每个特定组中有多少患者(按医院,按性别和年龄分类)。
如何在T-SQL中完成此类分组(最有效)?
答案 0 :(得分:3)
请试试这个
SELECT
DiseaseId,
SUM(CASE WHEN HospitalId = 0 AND GenderId=0 AND (Age BETWEEN 18 AND 30) THEN 1 ELSE 0 END) AS [HospitalA_Male_18-30],
SUM(CASE WHEN HospitalId = 0 AND GenderId=0 AND (Age BETWEEN 31 AND 40) THEN 1 ELSE 0 END) AS [HospitalA_Male_31-40],
SUM(CASE WHEN HospitalId = 0 AND GenderId=1 AND (Age BETWEEN 18 AND 30) THEN 1 ELSE 0 END) AS [HospitalA_Female_18-30],
......
FROM Patients
GROUP BY DiseaseId
ORDER BY DiseaseId
答案 1 :(得分:3)
您可以使用数据透视查询来执行此操作:
select * from
(
select diseaseid,
'Hospital'
+ case hospitalid when 0 then 'A' when 1 then 'B' end
+ '_'
+ case genderid when 1 then 'Female' else 'Male' end
+ '_'
+ case when age between 18 and 30
then '18-30'
else (case when age between 31 and 40 then '31-40' end)
end Title,
1 Cnt
from Patients
where age between 18 and 40
) t
pivot (
count (Cnt) for Title in (
[HospitalA_Male_18-30], [HospitalA_Male_31-40],
[HospitalA_Female_18-30], [HospitalA_Female_31-40],
[HospitalB_Male_18-30], [HospitalB_Male_31-40],
[HospitalB_Female_18-30], [HospitalB_Female_31-40]
)
) as Q
<强>更新强>
作为上述解决方案的开发,您还可以将名称部分从CASE表达式移动到它们自己的虚拟表,并将Patients
表连接到它们:
;with
hospital (hospitalid, hospitalname) as (
select 0, 'HospitalA' union all
select 1, 'HospitalB'
),
gender (genderid, gendername) as (
select 0, 'Male' union all
select 1, 'Female'
),
agerange (agefrom, ageto) as (
select 18, 30 union all
select 31, 40
)
select * from
(
select p.diseaseid,
h.hospitalname + '_' + g.gendername + '_'
+ rtrim(a.agefrom) + '-' + rtrim(a.ageto) as Title,
1 Cnt
from Patients p
inner join hospital h on p.hospitalid = h.hospitalid
inner join gender g on p.genderid = g.genderid
inner join agerange a on p.age between a.agefrom and a.ageto
where p.age between 18 and 40
) t
pivot (
count (Cnt) for Title in (
[HospitalA_Male_18-30], [HospitalA_Male_31-40],
[HospitalA_Female_18-30], [HospitalA_Female_31-40],
[HospitalB_Male_18-30], [HospitalB_Male_31-40],
[HospitalB_Female_18-30], [HospitalB_Female_31-40]
)
) as Q
添加子选择和连接的开销弥补了更容易的维护:
(meta)数据部分与逻辑部分分开;
根据需要,名称部分列表更方便扩展;
如果您需要更改目标列名称的格式,则更容易修改串联表达式。