多个聚合数据透视表

时间:2017-03-28 22:10:41

标签: sql sql-server tsql

我想要将几列数据放入数据透视表中。这是以下查询运行后数据当前的样子:

SELECT
    t.clinic,
    t.fiscal_year,
    t.total,
    n.new_pats,
    (t.total - n.new_pats) AS active
FROM (SELECT DISTINCT
    clinic,
    fiscal_year,
    COUNT(DISTINCT patient_id) AS total
FROM transactions t
JOIN period p
    ON (t.date_entered BETWEEN p.period_start AND p.period_end)
GROUP BY clinic, fiscal_year) t
JOIN (SELECT DISTINCT
    clinic,
    per.fiscal_year,
    COUNT(DISTINCT patient_id) AS new_pats
FROM patient pat
JOIN period per
    ON (pat.first_visit_date BETWEEN per.period_start AND per.period_end)
GROUP BY clinic, fiscal_year) n
    ON (t.clinic = n.clinic AND t.fiscal_year = n.fiscal_year)

enter image description here

我希望数据能够被他们自己行中的三个聚合分解,而这些年份就是这样的列:

enter image description here

每个聚合每年也可以分成3个单独的列,但这是我理想的目标。我之前没有在SQL中放置一个Pivot表,而且我不知所措。有没有更好的方法来以所需的方式格式化这些数据?

2 个答案:

答案 0 :(得分:1)

你可以试试这个

SELECT clinic, 
       aggregate_field, 
       ISNULL([2009],0) AS [2009], 
       ISNULL([2010],0) AS [2010], 
       ISNULL([2016],0) AS [2016], 
       ISNULL([2017],0) AS [2017]
FROM   (SELECT clinic, 
               fiscal_year, 
               aggregate_field, 
               value 
        FROM   (
                ------- This part is your original query -----------------
                SELECT t.clinic, 
                       t.fiscal_year, 
                       t.total, 
                       n.new_pats, 
                       ( t.total - n.new_pats ) AS active 
                FROM   (SELECT DISTINCT clinic, 
                                        fiscal_year, 
                                        Count(DISTINCT patient_id) AS total 
                        FROM   transactions t 
                               JOIN period p 
                                 ON ( t.date_entered BETWEEN 
                                      p.period_start AND p.period_end ) 
                        GROUP  BY clinic, fiscal_year) t 
                       JOIN (SELECT DISTINCT clinic, 
                                             per.fiscal_year, 
                                             Count(DISTINCT patient_id) AS new_pats 
                             FROM   patient pat 
                                    JOIN period per 
                                      ON ( pat.first_visit_date BETWEEN 
                                           per.period_start AND per.period_end ) 
                             GROUP  BY clinic, fiscal_year) n 
                         ON ( t.clinic = n.clinic 
                              AND t.fiscal_year = n.fiscal_year )
               -------------------------------------------------------------
               ) 
               unpivot_source 
               UNPIVOT ( value 
                       FOR aggregate_field IN (total, 
                                               new_pats, 
                                               active) ) unpivot_result) AS 
       pivot_source 
       PIVOT ( Max(value) 
             FOR fiscal_year IN ([2009], 
                                 [2010], 
                                 [2016], 
                                 [2017]) ) AS pivot_result 
ORDER  BY clinic, aggregate_field DESC 

我在这里创建了一个演示http://rextester.com/MFHWV68715

答案 1 :(得分:0)

试试这个:

CREATE TABLE #ActualData 
(
   Clinic varchar(50),
   fiscal_year int,
   total int,
   new_pats int,
   active int
)

INSERT INTO #ActualData VALUES ('A', 2016, 3538,1787,1751), ('A', 2017, 1218,373,845), ('B', 2009, 1,2,3), ('B', 2010, 1,2,3)

SELECT * FROM #ActualData ad

;WITH temps AS
   (
      SELECT Clinic, fiscal_year, aggregateF, Number FROM 
      (
         SELECT ad.Clinic, ad.fiscal_year, ad.total,ad.new_pats,ad.active FROM #ActualData ad
      ) src
      UNPIVOT
      (
         Number FOR aggregateF IN (total,new_pats ,active)
      ) unpvt
   )
SELECT Clinic, aggregateF, [2009],[2010],[2016],[2017]
FROM
(
   SELECT t.Clinic, t.aggregateF, t.fiscal_year, t.Number FROM temps t
) src
PIVOT
(
   MIN (Number) FOR fiscal_year IN ([2009],[2010],[2016],[2017])
) pvt
ORDER BY pvt.Clinic, pvt.aggregateF DESC

DROP TABLE #ActualData