zoukankan      html  css  js  c++  java
  • 一个交集数量统计图表的实现

    在一个报表系统项目中,客户提出一个较为特殊的需求:统计住院患者中不同症状的人数,除了显示每个指定症状的人数,还需要显示兼具多个症状的患者人数。
    下面让我们一起看一看使用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)设计图表
    拖放一个柱形图和表格,绑定数据集,如下图:

    注意:除了将【日期】字段拖放到图表的【分类】、【人数】字段拖放到图表的【数据字段】,还需将【症状】字段拖放到图表的【明细】和【颜色】部分,以便图表正确显示多个柱子和图例。

    报表预览效果如下图:

  • 相关阅读:
    insertSelective和insert的区别?
    @Valid和@BindingResult
    restful的put请求(坑),和HttpServletRequest做参数的作用
    ios网络编程读书笔记
    命令行杂记
    iOS杂记
    git项目收藏
    _Function_,_PRETTY_FUNCTION的区别
    iOS连接收藏
    转自别人的话
  • 原文地址:https://www.cnblogs.com/edoo/p/13501873.html
Copyright © 2011-2022 走看看