SQL Server将每个月的调查数据列表

时间:2017-06-15 08:55:27

标签: sql-server tsql server

我有一个包含许多列的调查表,但我关注的是这两个,survey_date和over_rating。我不确定是否可以在单个查询中完成。我正在使用sql server 2012.这是我的示例数据。

select survey_date, overall_rating from survey

survey_date             overall_rating
2017-01-06 15:09:51.940 6
2017-02-06 14:18:18.620 4
2017-05-07 16:03:12.037 7
2017-05-23 10:41:30.357 7
2017-05-23 10:41:30.357 5
2017-05-24 12:05:25.217 8
2017-06-01 09:03:47.727 7
2017-06-05 09:01:07.283 9
2017-06-05 09:28:12.597 6
2017-06-15 09:47:29.407 7
2017-07-06 12:10:50.003 2
2017-07-06 13:45:52.997 7
2017-08-06 14:00:35.403 5
2017-08-09 12:21:17.367 8

我需要计算每个等级1-10的发生次数,并将其总结。示例6月15日,评级10有1,评级9有10,... 这是结果表:

Month           10  9   8   7   6   5   4   3   2   1   Avg Score   Total   Total >=6   CSI
June'15         1   10  20  3   0   0   0   0   0   0   8           34      34          100%
July'15         1   16  14  0   0   0   0   0   1   0   9           32      31          99%
August'15       7   6   6   0   0   0   0   0   0   0   9           19      19          100%
September'15    0   2   2   0   0   0   0   0   0   0   9           4       4           100%
November'15     0   1   2   0   0   0   0   0   0   0   8           3       3           100%
December'15     0   7   3   4   2   0   0   0   0   0   8           16      16          100%

我尝试了这个查询,但部分错误,因为每个评级都有重复的月份:

select si.yr, si.mn, 
case when si.overall_rating = 10 then count(si.overall_rating) else 0 end as '10',
case when si.overall_rating = 9 then count(si.overall_rating) else 0 end as '9',
case when si.overall_rating = 8 then count(si.overall_rating) else 0 end as '8',
case when si.overall_rating = 7 then count(si.overall_rating) else 0 end as '7',
case when si.overall_rating = 6 then count(si.overall_rating) else 0 end as '6',
case when si.overall_rating = 5 then count(si.overall_rating) else 0 end as '5',
case when si.overall_rating = 4 then count(si.overall_rating) else 0 end as '4',
case when si.overall_rating = 3 then count(si.overall_rating) else 0 end as '3',
case when si.overall_rating = 2 then count(si.overall_rating) else 0 end as '2',
case when si.overall_rating = 1 then count(si.overall_rating) else 0 end as '1',
sum(si.overall_rating) as month_count
from
(select YEAR(s.survey_date) yr, MONTH(s.survey_date) mn, s.overall_rating
from survey s where s.status='Submitted' and s.survey_date >= '2017-01-01' AND s.survey_date <= '2017-12-31' 
group by YEAR(s.survey_date), MONTH(s.survey_date), s.overall_rating) si group by si.yr, si.mn, si.overall_rating;

结果:

yr      mm  10  9   8   7   6   5   4   3   2   1   total
2017    1   0   0   0   0   1   0   0   0   0   0   6
2017    2   0   0   0   0   0   0   1   0   0   0   4
2017    5   0   0   0   0   0   1   0   0   0   0   5
2017    5   0   0   0   1   0   0   0   0   0   0   7
2017    5   0   0   1   0   0   0   0   0   0   0   8
2017    6   0   0   0   0   1   0   0   0   0   0   6
2017    6   0   0   0   1   0   0   0   0   0   0   7
2017    6   0   1   0   0   0   0   0   0   0   0   9
2017    7   0   0   0   0   0   0   0   0   1   0   2
2017    7   0   0   0   1   0   0   0   0   0   0   7
2017    8   0   0   0   0   0   1   0   0   0   0   5
2017    8   0   0   1   0   0   0   0   0   0   0   8

如您所见,5和6重复不同的评级。如果有人能告诉我是否可以在一个查询中完成。感谢

3 个答案:

答案 0 :(得分:1)

我想我明白你要在这里实现的目标,你会很高兴知道你并不遥远。您在使用条件聚合时有正确的想法,但是您需要在聚合中包装条件case表达式,而不是相反。要执行条件count,您只需返回条件匹配的1和不匹配的0,然后sum结果。

这样做可以使group by保持简洁:

declare @t table(survey_date datetime,overall_rating int);
insert into @t values ('2017-01-06 15:09:51.940',6),('2017-02-06 14:18:18.620',4),('2017-05-07 16:03:12.037',7),('2017-05-23 10:41:30.357',7),('2017-05-23 10:41:30.357',5),('2017-05-24 12:05:25.217',8),('2017-06-01 09:03:47.727',7),('2017-06-05 09:01:07.283',9),('2017-06-05 09:28:12.597',6),('2017-06-15 09:47:29.407',7),('2017-07-06 12:10:50.003',2),('2017-07-06 13:45:52.997',7),('2017-08-06 14:00:35.403',5),('2017-08-09 12:21:17.367',8);

select dateadd(m,datediff(m,0,survey_date),0) as [Month]
        ,sum(case when overall_rating = 10 then 1 else 0 end) as [10]
        ,sum(case when overall_rating = 9 then 1 else 0 end) as [9]
        ,sum(case when overall_rating = 8 then 1 else 0 end) as [8]
        ,sum(case when overall_rating = 7 then 1 else 0 end) as [7]
        ,sum(case when overall_rating = 6 then 1 else 0 end) as [6]
        ,sum(case when overall_rating = 5 then 1 else 0 end) as [5]
        ,sum(case when overall_rating = 4 then 1 else 0 end) as [4]
        ,sum(case when overall_rating = 3 then 1 else 0 end) as [3]
        ,sum(case when overall_rating = 2 then 1 else 0 end) as [2]
        ,sum(case when overall_rating = 1 then 1 else 0 end) as [1]
        ,count(overall_rating) as ScoresReturned
        ,sum(overall_rating) as TotalScore
        ,avg(cast(overall_rating as decimal(10,0))) as Average
from @t
group by dateadd(m,datediff(m,0,survey_date),0)
order by [Month];

输出:

+-------------------------+----+---+---+---+---+---+---+---+---+---+----------------+------------+----------+
|          Month          | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | ScoresReturned | TotalScore | Average  |
+-------------------------+----+---+---+---+---+---+---+---+---+---+----------------+------------+----------+
| 2017-01-01 00:00:00.000 |  0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 |              1 |          6 | 6.000000 |
| 2017-02-01 00:00:00.000 |  0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 |              1 |          4 | 4.000000 |
| 2017-05-01 00:00:00.000 |  0 | 0 | 1 | 2 | 0 | 1 | 0 | 0 | 0 | 0 |              4 |         27 | 6.750000 |
| 2017-06-01 00:00:00.000 |  0 | 1 | 0 | 2 | 1 | 0 | 0 | 0 | 0 | 0 |              4 |         29 | 7.250000 |
| 2017-07-01 00:00:00.000 |  0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 1 | 0 |              2 |          9 | 4.500000 |
| 2017-08-01 00:00:00.000 |  0 | 0 | 1 | 0 | 0 | 1 | 0 | 0 | 0 | 0 |              2 |         13 | 6.500000 |
+-------------------------+----+---+---+---+---+---+---+---+---+---+----------------+------------+----------+

答案 1 :(得分:0)

select si.yr, si.mn, 
case when si.overall_rating = 10 then count(si.overall_rating) else 0 end as '10',
case when si.overall_rating = 9 then count(si.overall_rating) else 0 end as '9',
case when si.overall_rating = 8 then count(si.overall_rating) else 0 end as '8',
case when si.overall_rating = 7 then count(si.overall_rating) else 0 end as '7',
case when si.overall_rating = 6 then count(si.overall_rating) else 0 end as '6',
case when si.overall_rating = 5 then count(si.overall_rating) else 0 end as '5',
case when si.overall_rating = 4 then count(si.overall_rating) else 0 end as '4',
case when si.overall_rating = 3 then count(si.overall_rating) else 0 end as '3',
case when si.overall_rating = 2 then count(si.overall_rating) else 0 end as '2',
case when si.overall_rating = 1 then count(si.overall_rating) else 0 end as '1',
sum(si.overall_rating) as month_count
from
(select YEAR(s.survey_date) yr, MONTH(s.survey_date) mn, s.overall_rating
from survey s where s.status='Submitted' and s.survey_date >= '2017-01-01' AND s.survey_date <= '2017-12-31' 
group by YEAR(s.survey_date), MONTH(s.survey_date), s.overall_rating) si group by si.yr, si.mn;

您必须删除si.overall_rating

中的Group By

答案 2 :(得分:0)

Oh! I posted late, anyway you can try this otherwise.

DATA:

        IF ( OBJECT_ID('tempdb..#temptable') IS NOT NULL )
            BEGIN
                DROP TABLE #temptable
            END

        CREATE TABLE #temptable
            (
              survey_date DATETIME ,
              overall_rating NUMERIC(22,2)
            )

        INSERT  INTO #temptable
                ( survey_date, overall_rating )
        VALUES  ( '2017-01-06 15:09:51.940', 6 ),
                ( '2017-02-06 14:18:18.620', 4 ),
                ( '2017-05-07 16:03:12.037', 7 ),
                ( '2017-05-23 10:41:30.357', 7 ),
                ( '2017-05-23 10:41:30.357', 5 ),
                ( '2017-05-24 12:05:25.217', 8 ),
                ( '2017-06-01 09:03:47.727', 7 ),
                ( '2017-06-05 09:01:07.283', 9 ),
                ( '2017-06-05 09:28:12.597', 6 ),
                ( '2017-06-15 09:47:29.407', 7 ),
                ( '2017-07-06 12:10:50.003', 2 ),
                ( '2017-07-06 13:45:52.997', 7 ),
                ( '2017-08-06 14:00:35.403', 5 ),
                ( '2017-08-09 12:21:17.367', 8 )

QUERY:

                ;
        WITH    CTE
                  AS ( SELECT   DATENAME(month, survey_date) + ' '''
                                + RIGHT(CAST(YEAR(survey_date) AS NVARCHAR(4)),
                                        2) AS [Month] ,
                                ISNULL([1], 0) [1] ,
                                ISNULL([2], 0) [2] ,
                                ISNULL([3], 0) [3] ,
                                ISNULL([4], 0) [4] ,
                                ISNULL([5], 0) [5] ,
                                ISNULL([6], 0) [6] ,
                                ISNULL([7], 0) [7] ,
                                ISNULL([8], 0) [8] ,
                                ISNULL([9], 0) [9] ,
                                ISNULL([10], 0) [10],
                                Total,
                                Average
                       FROM     ( SELECT    survey_date ,
                                            COUNT(overall_rating) overall_rating,
                                            CAST(SUM(overall_rating) AS INT) Total,
                                            AVG(overall_rating) Average
                                  FROM      ( SELECT    DATEADD(MONTH,
                                                          DATEDIFF(MONTH,
                                                          0, survey_date),
                                                          0) survey_date ,
                                                        overall_rating
                                              FROM      #temptable
                                            ) T
                                  GROUP BY  t.survey_date
                                ) PVT PIVOT ( SUM(overall_rating) FOR overall_rating IN ( [1],
                                                          [2], [3], [4],
                                                          [5], [6], [7],
                                                          [8], [9], [10] ) ) P
                     )
            SELECT  [Month] ,
                    ISNULL([1], 0) [1] ,
                    ISNULL([2], 0) [2] ,
                    ISNULL([3], 0) [3] ,
                    ISNULL([4], 0) [4] ,
                    ISNULL([5], 0) [5] ,
                    ISNULL([6], 0) [6] ,
                    ISNULL([7], 0) [7] ,
                    ISNULL([8], 0) [8] ,
                    ISNULL([9], 0) [9] ,
                    ISNULL([10], 0) [10],
                    Total,
                    Average
            FROM    CTE

RESULT:

        Month                   1      2    3     4     5     6     7    8    9     10    Total       Average
        ----------------------- ------ ---- ----- ----- ----- ----- ---- ---- ----- ----- ----------- -------------
        January '17             1      0    0     0     0     0     0    0    0     0     6           6.000000
        February '17            1      0    0     0     0     0     0    0    0     0     4           4.000000
        May '17                 0      0    0     4     0     0     0    0    0     0     27          6.750000
        June '17                0      0    0     4     0     0     0    0    0     0     29          7.250000
        July '17                0      2    0     0     0     0     0    0    0     0     9           4.500000
        August '17              0      2    0     0     0     0     0    0    0     0     13          6.500000

        (6 row(s) affected)