在一个报表系统项目中,客户提出一个较为特殊的需求:统计住院患者中不同症状的人数,除了显示每个指定症状的人数,还需要显示兼具多个症状的患者人数。
下面让我们一起看一看使用Wyn Enterprise时的一些技巧。
例如:指定【发热】和【咳嗽】两个症状,除了显示发热患者人数和咳嗽患者人数,还需要显示既有发热症状、也有咳嗽症状的患者人数。如下图:
图中的兼具多症状的患者人数,实际上是一种交集的数量统计。
原始数据是一种类似病院查房日志的记录,每个病人每天可能有多条记录,而且同日多条记录的症状还可能是重复的。
实现这种需求的思路:
(1)剔除同一患者同一天同种症状的重复记录
每个患者一天之内可能多次检查,每次记录的症状可能重复,比如早上记录时有发热症状,下午又有发热症状。
为了防止同一个同一个患者被统计成两个或者更多的人数,首先就需要保证同一患者同一症状在同一天内只能有0或1条记录。
(2)采用多次查询的方法获取多症状患者人数
(3)将单症状人数统计结果与多症状统计结果做联合(UNION)
以下介绍具体操作。
(一)剔除重复记录
原始数据【病例】表的记录如下图:
下面是数据表的创建和数据初始化脚本:
CREATE TABLE [dbo].[病例](
[ID] [int] NOT NULL,
[姓名] [nvarchar](50) NULL,
[症状] [nvarchar](50) NULL,
[日期] [date] NULL,
CONSTRAINT [PK_病例] PRIMARY KEY CLUSTERED
(
[ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
INSERT [dbo].[病例] ([ID], [姓名], [症状], [日期]) VALUES (1, N'张三', N'001-发热', CAST(N'2020-03-18' AS Date))
INSERT [dbo].[病例] ([ID], [姓名], [症状], [日期]) VALUES (2, N'李四', N'002-咳嗽', CAST(N'2020-03-18' AS Date))
INSERT [dbo].[病例] ([ID], [姓名], [症状], [日期]) VALUES (3, N'张三', N'002-咳嗽', CAST(N'2020-03-18' AS Date))
INSERT [dbo].[病例] ([ID], [姓名], [症状], [日期]) VALUES (4, N'张三', N'001-发热', CAST(N'2020-03-18' AS Date))
INSERT [dbo].[病例] ([ID], [姓名], [症状], [日期]) VALUES (5, N'赵六', N'001-发热', CAST(N'2020-03-18' AS Date))
INSERT [dbo].[病例] ([ID], [姓名], [症状], [日期]) VALUES (6, N'赵六', N'002-咳嗽', CAST(N'2020-03-18' AS Date))
INSERT [dbo].[病例] ([ID], [姓名], [症状], [日期]) VALUES (7, N'张三', N'003-流涕', CAST(N'2020-03-18' AS Date))
INSERT [dbo].[病例] ([ID], [姓名], [症状], [日期]) VALUES (8, N'李四', N'003-流涕', CAST(N'2020-03-18' AS Date))
INSERT [dbo].[病例] ([ID], [姓名], [症状], [日期]) VALUES (9, N'李四', N'001-发热', CAST(N'2020-03-19' AS Date))
INSERT [dbo].[病例] ([ID], [姓名], [症状], [日期]) VALUES (10, N'张三', N'003-流涕', CAST(N'2020-03-19' AS Date))
INSERT [dbo].[病例] ([ID], [姓名], [症状], [日期]) VALUES (11, N'赵六', N'001-发热', CAST(N'2020-03-19' AS Date))
INSERT [dbo].[病例] ([ID], [姓名], [症状], [日期]) VALUES (12, N'李四', N'003-流涕', CAST(N'2020-03-19' AS Date))
INSERT [dbo].[病例] ([ID], [姓名], [症状], [日期]) VALUES (13, N'赵六', N'003-流涕', CAST(N'2020-03-19' AS Date))
INSERT [dbo].[病例] ([ID], [姓名], [症状], [日期]) VALUES (14, N'李四', N'002-咳嗽', CAST(N'2020-03-19' AS Date))
ALTER TABLE [dbo].[病例] ADD CONSTRAINT [DF_病例_日期] DEFAULT (getdate()) FOR [日期]
GO
可以看到,患者张三在2020-3-18这一天,记录了两次发热症状。为了剔除重复记录,用带有distinct关键字的SQL语句:
select distinct 日期,症状,姓名 from 病例
(二)查询兼具多种症状的患者人数
如果用户指定了【发热】和【咳嗽】两种症状,为了查到同时具有这两种症状的患者人数,首先以上面剔除重复记录的结果为基础,查询每个患者每天每个症状的记录数。结果是仅有指定两种症状的记录,即不含【流涕】等其他症状。
如果一个患者在某一天没有指定的症状,或者只有两种症状中的一种,那么该患者当天的记录条数为0或者1,否则记录条数就是2。记录数为2的那些患者就是同时兼具两种症状的患者。
查询语句如下:
select 日期,姓名,count(*) C
from ( select distinct 日期,症状,姓名 from 病例 ) T1
where 症状 in ( '001-发热','002-咳嗽' )
group by 日期,姓名
查询结果如下图:
其中最后一列C中,数字为2的就是当天兼具两种症状的患者。
以此为基础,可统计每天的兼具多症状的患者人数:
select 日期, '999-兼具多症状' ,count(*)
from
(
select 日期,姓名,count(*) C
from ( select distinct 日期,症状,姓名 from 病例 ) T1
where 症状 in ( '001-发热','002-咳嗽' )
group by 日期,姓名
) T3
where C>=2
group by 日期
结果如下图:
(三)单症状人数统计结果与多症状统计结果做联合
单症状人数统计的查询比较简单:
select B.日期,A.症状,count(B.姓名) 人数
from
(select distinct 症状 from 病例) A
, ( select distinct 日期,症状,姓名 from 病例 ) B
where B.症状=A.症状
and B.症状 in ( '001-发热','002-咳嗽' )
group by B.日期,A.症状
以此为基础,联合前面的兼具多症状患者查询结果,查询语句就成为:
select B.日期,A.症状,count(B.姓名) 人数
from
(select distinct 症状 from 病例) A
, ( select distinct 日期,症状,姓名 from 病例 ) B
where B.症状=A.症状
and B.症状 in ( '001-发热','002-咳嗽' )
group by B.日期,A.症状
UNION -- 联合!!
select 日期, '999-兼具多症状' ,count(*)
from
(
select 日期,姓名,count(*) C
from ( select distinct 日期,症状,姓名 from 病例 ) T1
where 症状 in ( '001-发热','002-咳嗽' )
group by 日期,姓名
) T3
where C>=2
group by 日期
查询结果如下图:
(四)报表设计
(1)报表参数定义
在报表设计中,为了允许用户指定症状种类,定义一个多值参数【症状参数】,以下拉列表形式列出【发热】【咳嗽】【流涕】等症状条目。如下图:
(2)数据集设计
在数据集的对话框中,定义两个查询参数:
症状参数 =Parameters!症状参数.Value
症状参数值个数 =Parameters!症状参数.Value.GetLength(0)
如下图:
注意:第二个查询参数的表达式中,使用GetLength(0)方法,获取用户选取的症状条目个数。
数据集的查询语句中,应将上面的示例脚本中的固定条件改为参数形式:
select B.日期,A.症状,count(B.姓名) 人数
from
(select distinct 症状 from temp..病例) A
, ( select distinct 日期,症状,姓名 from temp..病例 ) B
where B.症状=A.症状
and B.症状 in ( @症状参数 )
group by B.日期,A.症状
UNION
select 日期, '999-兼具多症状' ,count(*)
from
(
select 日期,姓名,count(*) C
from ( select distinct 日期,症状,姓名 from temp..病例 ) T1
where 症状 in ( @症状参数 )
group by 日期,姓名
) T3
where C>= @症状参数值个数
group by 日期
(3)设计图表
拖放一个柱形图和表格,绑定数据集,如下图:
注意:除了将【日期】字段拖放到图表的【分类】、【人数】字段拖放到图表的【数据字段】,还需将【症状】字段拖放到图表的【明细】和【颜色】部分,以便图表正确显示多个柱子和图例。
报表预览效果如下图: