首页 > IT职业 > IT职场 > sql统计各种奇葩的数据库表数据
| 关联id | 疾病名称 |
|---|---|
| 1 | 高血压 |
| 1 | 糖尿病 |
| 2 | 脑梗 |
| 3 | 心脏病 |
group by一下就行| 房间id | 床位 | 状态 |
|---|---|---|
| 1 | C1 | 2 |
| 1 | C2 | 1 |
| 1 | C3 | 1 |
| 1 | C4 | 1 |
| 2 | C1 | 2 |
| 2 | C2 | 0 |
| 2 | C3 | 0 |
| 2 | C4 | 0 |
SELECT COUNT(a.DiseaseType) AS Num, a.DiseaseType as jk_zyjb FROM
(
Select
a.Id,
a.jk_zyjb 疾病,
b.number,
substring(a.jk_zyjb,b.number, charindex('+',a.jk_zyjb+'+',b.number)-b.number) as DiseaseType
From Dict_Oldie a WITH (NOLOCK), master..spt_values b WITH (NOLOCK)
WHERE
jk_zyjb IS NOT NULL AND
b.type='p'AND b.number > 0 AND
b.number <= LEN(a.jk_zyjb) AND
substring('+'+a.jk_zyjb, b.number,1) = '+'
GROUP BY a.jk_zyjb,a.Id,b.number
) as a
GROUP BY a.DiseaseType
以上子查询的结果是
最终结果
上面代码主要是利用master..spt_values表的p类型数据,0-2047,与目标表进行联合查询,遍历每个number,截取字符分隔的词。
查询中的substring函数用于截取疾病名称,其中的charindex函数用于查找疾病名称的长度,where中的substring用于确定number是否是开始截取的位置,每一处都很关键,这里不过多解释,多试几遍就理解了
SELECT a.BedStatus,COUNT(a.BedStatus) Num,
BedStatusStr=(CASE a.BedStatus
WHEN 1 THEN '空闲'
WHEN 2 THEN '使用'
WHEN 3 THEN '外出'
ELSE '试住'
END)
FROM
(SELECT Id, BedStatus=(CASE b.number
WHEN 0 THEN C1
WHEN 1 THEN C2
WHEN 2 THEN C3
ELSE C4
END)
FROM Room a WITH (NOLOCK), master..spt_values b WITH (NOLOCK)
WHERE
b.type = 'p' AND b.number < 4) a
WHERE a.BedStatus!=0
GROUP BY a.BedStatus

最终结果
以上,相当于联合一张只有[1,2,3,4]四个数据的表,用循环,分支判断将四个字段转换成一列,得到上述中间表结构,再按需求进行统计
master..spt_values、WITH (NOLOCK)。master..spt_values是个存有各种常用数据的表,也可以自己构造,个人感觉使用还是挺广泛的,这个表也是第一次用,给解决问题提供了不错的思路。WITH (NOLOCK),字面意思就是不加锁嘛,由于我只是读取数据统计,就算脏读也无所谓,加上这个据说性能更好,没验证过master..spt_values这个表,应用挺多的,但是在不知道它之前真的没有思路,差点就放弃了用SQL,将全部数据取出来在代码里循环处理。来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/3244/viewspace-2820552/ ,如需转载,请注明出处,否则将追究法律责任。