SQL Server:按计算列分组

时间:2017-10-25 03:50:44

标签: sql tsql

我有一个包含这样的列的表:

enter image description here

我想知道该期间每个问题的平均合规率。 我将开始日期和结束日期作为参数进行查询。

因此,如果我想要两个时期,我将在第一个时段@StartDate(例如1/6/17)和@EndDate(例如30/6/17)通过@StartDate2(第二期的1/10/17)和@EndDate2(31/10/17)。

我的SQL查询是:

;WITH tmpTab AS
(
    SELECT
        question, 
        SUM((CASE WHEN AnswerValue = 1 THEN 1 ELSE 0 END)) Met,
        SUM((CASE WHEN AnswerValue = 3 THEN 1 ELSE 0 END)) NA,
        SUM((CASE WHEN (ISNULL(AnswerValue,3) <> 3) THEN 1 ELSE 0 END)) MetNotMet,
        DATENAME(DAY, @StartDate) + ' ' + DATENAME(MONTH, @StartDate) + ' ' + 
            DATENAME(YEAR, @StartDate) + ' To ' + DATENAME(DAY,@EndDate) + ' ' +
            DATENAME(MONTH, @EndDate) + ' ' + DATENAME(YEAR, @EndDate) AS RepMonthAndYear
    FROM
        tableA 
    WHERE
        startdate >= @StartDate AND endate <= @EndDate
    GROUP BY
        Question

    UNION ALL

    SELECT 
        question, 
        SUM((CASE WHEN AnswerValue = 1 THEN 1 ELSE 0 END)) Met,
        SUM((CASE WHEN AnswerValue = 3 THEN 1 ELSE 0 END)) NA,
        SUM((CASE WHEN (ISNULL(AnswerValue,3) <> 3) THEN 1 ELSE 0 END)) MetNotMet,
        DATENAME(DAY,@StartDate2)+' '+DATENAME(MONTH,@StartDate2)+' '+DATENAME(YEAR,@StartDate2)+ ' To ' + DATENAME(DAY,@EndDate2)+' '+DATENAME(MONTH,@EndDate2)+' '+DATENAME(YEAR,@EndDate2) AS RepMonthAndYear
    FROM
        tableA  
    WHERE
        startdate >= @StartDate2 AND endate <= @EndDate2
    GROUP BY 
        Question
)
SELECT 
    Question, Met, NA, MetNotMet,
    CASE WHEN (Met) = 0 THEN 0 ELSE ROUND(((CONVERT(FLOAT,(Met))/(MetNotMet))* 100),4) END as CompRate
FROM
    tmpTab

在这个SQL查询中,我需要按RepMonthAndYear列分组,我不能这样做,因为它是一个计算列。我收到错误&#34;无效的列&#34;。

如果我使用这个GROUP BY条款:

(DATENAME(DAY,@StartDate2)+' '+DATENAME(MONTH,@StartDate2)+' '+DATENAME(YEAR,@StartDate2)+ ' To ' + DATENAME(DAY,@EndDate2)+' '+DATENAME(MONTH,@EndDate2)+' '+DATENAME(YEAR,@EndDate2) )

我收到此错误:

  

每个GROUP BY表达式必须至少包含一个不是外部引用的列。

我该如何解决这个问题?

有没有其他方法可以了解特定时期的平均费率组?

1 个答案:

答案 0 :(得分:0)

鉴于以下测试数据和您的SQL,我得到了您的意见。

CREATE TABLE tableA (
   question     VARCHAR(50),
   AnswerValue  INT,
   startdate    DATE,
   endate       DATE
);

INSERT INTO tableA VALUES ('Question A', 1, '2017-06-25', '2017-06-26');
INSERT INTO tableA VALUES ('Question A', 1, '2017-06-27', '2017-06-27');
INSERT INTO tableA VALUES ('Question A', 2, '2017-06-27', '2017-06-27');
INSERT INTO tableA VALUES ('Question B', 1, '2017-06-11', '2017-06-12');
INSERT INTO tableA VALUES ('Question B', 2, '2017-06-13', '2017-06-13');
INSERT INTO tableA VALUES ('Question B', 1, '2017-06-13', '2017-06-13');
INSERT INTO tableA VALUES ('Question C', 1, '2017-06-20', '2017-06-20');
INSERT INTO tableA VALUES ('Question C', 1, '2017-06-23', '2017-06-23');
INSERT INTO tableA VALUES ('Question D', 2, '2017-06-01', '2017-06-01');

INSERT INTO tableA VALUES ('Question E', 1, '2017-10-11', '2017-10-11');
INSERT INTO tableA VALUES ('Question E', 1, '2017-10-15', '2017-10-15');
INSERT INTO tableA VALUES ('Question F', 1, '2017-10-20', '2017-10-20');
INSERT INTO tableA VALUES ('Question F', 2, '2017-10-20', '2017-10-20');
INSERT INTO tableA VALUES ('Question F', 2, '2017-10-20', '2017-10-20');
INSERT INTO tableA VALUES ('Question G', 1, '2017-10-26', '2017-10-26');
INSERT INTO tableA VALUES ('Question H', 1, '2017-10-26', '2017-10-26');
INSERT INTO tableA VALUES ('Question H', 2, '2017-10-26', '2017-10-26');
INSERT INTO tableA VALUES ('Question I', 1, '2017-10-26', '2017-10-26');

您的查询结果:

Question A  2   0   3   66,6667
Question B  2   0   3   66,6667
Question C  2   0   2   100
Question D  0   0   1   0
Question E  2   0   2   100
Question F  1   0   3   33,3333
Question G  1   0   1   100
Question H  1   0   2   50
Question I  1   0   1   100

我可以简化你的SQL并删除了一些代码重复,也许这是你想要的问题。

DECLARE @StartDate DATE = '2017-06-01';
DECLARE @EndDate DATE = '2017-06-30';
DECLARE @StartDate2 DATE = '2017-10-01';
DECLARE @EndDate2 DATE = '2017-10-30';

WITH 
periods AS (
SELECT @StartDate as startdate,
       @EndDate   as enddate       
UNION 
SELECT @StartDate2 as startdate,
       @EndDate2   as enddate
)
SELECT t.Question, t.Met, t.NA, t.MetNotMet,
       CASE WHEN (t.Met) = 0 THEN 0 ELSE ROUND(((CONVERT(FLOAT,(t.Met))/(t.MetNotMet))* 100),4) END as CompRate
  FROM (SELECT question, 
               SUM((CASE WHEN AnswerValue = 1 THEN 1 ELSE 0 END)) Met,
               SUM((CASE WHEN AnswerValue = 3 THEN 1 ELSE 0 END)) NA,
               SUM((CASE WHEN (ISNULL(AnswerValue,3) <> 3) THEN 1 ELSE 0 END)) MetNotMet       
          FROM tableA AS a
          JOIN ( SELECT p.startdate,
                        p.enddate,
                        DATENAME(DAY, p.startdate) + ' ' + DATENAME(MONTH, p.startdate) + ' ' + 
                          DATENAME(YEAR, p.startdate) + ' To ' + DATENAME(DAY, p.enddate) + ' ' +
                          DATENAME(MONTH, p.enddate) + ' ' + DATENAME(YEAR, p.enddate) AS RepMonthAndYear
                   FROM periods p ) AS p ON a.startdate >= p.startdate AND a.endate <= p.enddate
         GROUP BY a.Question, p.RepMonthAndYear) AS t