在SQL Server中明智的患者数量

时间:2013-08-07 15:27:45

标签: sql sql-server group-by

select distinct
    Patient_Ref_master.Dept_ID as 'dept',
    Patient_Ref_master.Male_femal as 'Gender',
    count(Patient_Ref_master.Pat_ID) as 'count'
from 
    Patient_Ref_master
left join 
    Patient_Master on Patient_Master.Pat_Code=Patient_Ref_master.Pat_ID
where 
    (Patient_Ref_master.Age > 16 
     and dbo.Patient_Master.Pat_Sex = 2 
     and Patient_Ref_master.creation_Date = '2013/08/02') 
    or 
    (Patient_Ref_master.Age > 16 
     and dbo.Patient_Master.Pat_Sex = 1 
     and Patient_Ref_master.creation_Date = '2013/08/02') 
    or
    (Patient_Ref_master.Age >= 0 
     and Patient_Ref_master.Age <= 16 
     and dbo.Patient_Master.Pat_Sex = 2 
     and Patient_Ref_master.creation_Date = '2013/08/02') 
    or
    (Patient_Ref_master.Age >= 0 
     and Patient_Ref_master.Age <= 16 
     and dbo.Patient_Master.Pat_Sex = 1 
     and Patient_Ref_master.creation_Date = '2013/08/02') 
group by 
    Patient_Ref_master.Male_femal, Patient_Ref_master.Dept_ID

上面是我的查询,它返回一个表格如下

  Dept    Gender           Count
    102    Females   3
    102    Males     4
    103    Boys          2
    103    Females   2
    103    Girls     1
    103    Males     1
    104    Females   6
    104    Males     1

根据部门,我在这里得到了男性,女性,女孩和男孩的统计数据。但我希望输出以下列方式显示

 Dept    Males Females Boys Girls 
    102    3        2     5     5  
    103    4        5     2     6   
    104    2        1     1     5

这是男孩,女孩,男性和女性的部门计数。我需要做些什么来获得类似上面的模式? Pivot可以选择吗?我从未使用Pivot

请帮忙。 感谢

2 个答案:

答案 0 :(得分:3)

是的,PIVOT是解决方案

select *
from 
     ( 
        -- your query here
     ) d
    pivot (sum([count]) for gender in (females,males,boys,girls)) p

或更好

select *
from 
     ( 
         select 
              Patient_Ref_master.Dept_ID,
              Patient_Ref_master.Male_femal,      
         from Patient_Ref_master
         left join Patient_Master on Patient_Master.Pat_Code=Patient_Ref_master.Pat_ID
         where 
             -- your filter here
     ) d
    pivot (count(pat_code) for Male_femal in (females,males,boys,girls)) p

请参阅http://technet.microsoft.com/en-us/library/ms177410(v=sql.105).aspx

答案 1 :(得分:2)

;WITH MyCTE AS
(
    SELECT    DISTINCT
              Patient_Ref_master.Dept_ID AS 'dept',
              Patient_Ref_master.Male_femal AS 'Gender',
              COUNT(Patient_Ref_master.Pat_ID) AS 'count'
    FROM      Patient_Ref_master
              LEFT JOIN Patient_Master 
                  ON Patient_Master.Pat_Code = Patient_Ref_master.Pat_ID
    WHERE    (
                  Patient_Ref_master.Age > 16 
                  AND dbo.Patient_Master.Pat_Sex = 2 
                  AND Patient_Ref_master.creation_Date = '2013/08/02'
             )
             OR
             (
                  Patient_Ref_master.Age > 16 
                  AND dbo.Patient_Master.Pat_Sex = 1 
                  AND Patient_Ref_master.creation_Date = '2013/08/02'
             )
             OR
             (
                  Patient_Ref_master.Age >= 0 
                  AND Patient_Ref_master.Age <= 16 
                  AND dbo.Patient_Master.Pat_Sex = 2 
                  AND Patient_Ref_master.creation_Date = '2013/08/02'
             )
             OR
             (
                  Patient_Ref_master.Age >= 0 
                  AND Patient_Ref_master.Age <= 16 
                  AND dbo.Patient_Master.Pat_Sex = 1 
                  AND Patient_Ref_master.creation_Date = '2013/08/02'
             )
    GROUP BY Patient_Ref_master.Male_femal,
             Patient_Ref_master.Dept_ID
)
SELECT     Dept,
           [Males], 
           [Females], 
           [Boys], 
           [Girls]
FROM       (
               SELECT Gender, 
                      Count ,
                      Dept
               FROM   MyCTE
           ) AS SourceTable
PIVOT
(
    MAX(Count)
    FOR Gender IN ([Males], [Females], [Boys], [Girls])
) AS PivotTable

WITH MyCTE AS ...块定义了公用表表达式。它是一种在运行中定义类似于视图的方法。在这种情况下,我使用它以使代码更具可读性。您可以在Using Common Table Expressions

上找到更多信息

然后PIVOT代码是一种将表行转换为列的方法,这实际上就是你要求的。您可以省略CTE部分,并且在PIVOT的FROM子句中,您可以添加您的代码,但这有点难以理解。有关PIVOT Using PIVOT and UNPIVOT

的更多信息

不幸的是,PIVOT的工作方式,你只能在那里定义三列

  1. 将成为结果表“ID”的一个
  2. 包含您想要显示为行的值的文件
  3. 最后一个包含你需要的聚合
  4. 所以PIVOT就是那样而没有别的。但是PIVOT仍然是一张桌子,你可以和其他桌子一起加入。

    作为补充,我还必须注意,您可以定义多个CTE,每个CTE包含先前定义的引用。语法是:

    ;WITH CTE1 AS
    (
      CTE1 SELECT
    )
    , CTE2
    (
      CTE2 SELECT ... May refer to CTE1
    )
    

    因此,一个完整的答案将是:

    ;WITH MyCTE AS
    (
        SELECT    DISTINCT
                  Patient_Ref_master.Dept_ID AS 'dept',
                  Patient_Ref_master.Male_femal AS 'Gender',
                  COUNT(Patient_Ref_master.Pat_ID) AS 'count'
        FROM      Patient_Ref_master
                  LEFT JOIN Patient_Master 
                      ON Patient_Master.Pat_Code = Patient_Ref_master.Pat_ID
        WHERE    (
                      Patient_Ref_master.Age > 16 
                      AND dbo.Patient_Master.Pat_Sex = 2 
                      AND Patient_Ref_master.creation_Date = '2013/08/02'
                 )
                 OR
                 (
                      Patient_Ref_master.Age > 16 
                      AND dbo.Patient_Master.Pat_Sex = 1 
                      AND Patient_Ref_master.creation_Date = '2013/08/02'
                 )
                 OR
                 (
                      Patient_Ref_master.Age >= 0 
                      AND Patient_Ref_master.Age <= 16 
                      AND dbo.Patient_Master.Pat_Sex = 2 
                      AND Patient_Ref_master.creation_Date = '2013/08/02'
                 )
                 OR
                 (
                      Patient_Ref_master.Age >= 0 
                      AND Patient_Ref_master.Age <= 16 
                      AND dbo.Patient_Master.Pat_Sex = 1 
                      AND Patient_Ref_master.creation_Date = '2013/08/02'
                 )
        GROUP BY Patient_Ref_master.Male_femal,
                 Patient_Ref_master.Dept_ID
    )
    ,PivotCTE AS
    (
        SELECT     Dept,
                   [Males], 
                   [Females], 
                   [Boys], 
                   [Girls]
        FROM       (
                       SELECT Gender, 
                              Count ,
                              Dept
                       FROM   MyCTE
                   ) AS SourceTable
        PIVOT
        (
            MAX(Count)
            FOR Gender IN ([Males], [Females], [Boys], [Girls])
        ) AS PivotTable
    )
    SELECT    Dept,
              DeptName
              [Males], 
              [Females], 
              [Boys], 
              [Girls]
    FROM      PivotCTE P
              JOIN DepartmentTable D
                   ON P.Dept = D.Dept