按整周分组的总计

时间:2015-12-09 22:55:42

标签: sql-server

理想情况下,我希望下面的内容更加紧凑,即每周删除一周的总计重复次数,并在几周内进行某种形式的迭代。如果它可以通过存储过程总计是完美的,使用“周回来”int,它将整整几周,然后(wishlist项目)总计当前这周的数据。鉴于以下情况,这可能吗?即exec spGetTotalsWeeksBack 8,将看起来8周后,总共只有整整一周,(如果开始日期参数不是星期日,则转到下一个星期日作为第1周输出)。 我也遇到ISNULL的问题,即使是0,它仍然没有返回所有客户。任何帮助都表示赞赏!

DECLARE @reportStartDate DATE = '2015-06-28' /*A Sunday, report start date*/

SELECT a.ClientName
    ,ISNULL(COUNT(CASE 
                WHEN DATEDIFF(week, @reportStartDate, RecordCreateDate) = 0
                    THEN 1
                END), 0) AS 'Week 1'
    ,ISNULL(COUNT(CASE 
                WHEN DATEDIFF(week, @reportStartDate, RecordCreateDate) = 1
                    THEN 1
                END), 0) AS 'Week 2'
    ,ISNULL(COUNT(CASE 
                WHEN DATEDIFF(week, @reportStartDate, RecordCreateDate) = 2
                    THEN 1
                END), 0) AS 'Week 3'
    ,ISNULL(COUNT(CASE 
                WHEN DATEDIFF(week, @reportStartDate, RecordCreateDate) = 3
                    THEN 1
                END), 0) AS 'Week 4'
FROM Client a WITH (NOLOCK)
LEFT JOIN SecondaryClient b WITH (NOLOCK) ON b.MainClientID = a.ClientID
LEFT JOIN RecordLog c WITH (NOLOCK) ON c.ClientID = b.ClientID
    AND c.RecordCreateDate BETWEEN @reportStartDate /*Sunday, report start date*/
        AND DATEADD(week, 4, @reportStartDate) /* Saturday, report end date */
LEFT JOIN IncomingData d WITH (NOLOCK) ON d.DataID = c.DataID
    AND d.DataReceiveDate > @reportStartDate
    AND d.DataSourceID = 10
WHERE a.StatusID = 1
    AND a.ClientID IN (
        SELECT clientid
        FROM clientsettings
        WHERE active = 1
        )
GROUP BY a.ClientName
ORDER BY a.ClientName

1 个答案:

答案 0 :(得分:0)

这里有2个问题。

  1. “我在ISNULL遇到问题,即使0”仍然没有返回所有客户端
  2. 您遇到此问题,因为您正在对LEFT JOIN-ed表进行过滤。

    将重写查询视为UNION ALL的2个查询,每个查询都使用INNER JOINS:

    DECLARE @reportStartDate DATE = '2015-06-28' /*A Sunday, report start date*/
    
    SELECT a.ClientName
        ,COUNT(CASE 
                    WHEN DATEDIFF(week, @reportStartDate, RecordCreateDate) = 0
                        THEN 1
                    END), 0) AS 'Week 1'
        ,COUNT(CASE 
                    WHEN DATEDIFF(week, @reportStartDate, RecordCreateDate) = 1
                        THEN 1
                    END), 0) AS 'Week 2'
        ,COUNT(CASE 
                    WHEN DATEDIFF(week, @reportStartDate, RecordCreateDate) = 2
                        THEN 1
                    END), 0) AS 'Week 3'
        ,COUNT(CASE 
                    WHEN DATEDIFF(week, @reportStartDate, RecordCreateDate) = 3
                        THEN 1
                    END), 0) AS 'Week 4'
    FROM Client a WITH (NOLOCK)
    JOIN SecondaryClient b WITH (NOLOCK) ON b.MainClientID = a.ClientID
    JOIN RecordLog c WITH (NOLOCK) ON c.ClientID = b.ClientID
        AND c.RecordCreateDate BETWEEN @reportStartDate /*Sunday, report start date*/
            AND DATEADD(week, 4, @reportStartDate) /* Saturday, report end date */
    JOIN IncomingData d WITH (NOLOCK) ON d.DataID = c.DataID
        AND d.DataReceiveDate > @reportStartDate
        AND d.DataSourceID = 10
    WHERE a.StatusID = 1
        AND a.ClientID IN (
            SELECT clientid
            FROM clientsettings
            WHERE active = 1
            )
    GROUP BY a.ClientName
    UNION ALL -- non existent values
    SELECT DISTINCT a.client, Week1=0, Week2=0,Week3=0, Week4=0
    FROM Client a WITH (NOLOCK)
    WHERE NOT EXISTS (
        SELECT * FROM 
        SecondaryClient b WITH (NOLOCK) ON b.MainClientID = a.ClientID
        JOIN RecordLog c WITH (NOLOCK) ON c.ClientID = b.ClientID
            AND c.RecordCreateDate BETWEEN @reportStartDate /*Sunday, report start date*/
                AND DATEADD(week, 4, @reportStartDate) /* Saturday, report end date */
        JOIN IncomingData d WITH (NOLOCK) ON d.DataID = c.DataID
            AND d.DataReceiveDate > @reportStartDate
            AND d.DataSourceID = 10
        WHERE a.StatusID = 1
            AND a.ClientID IN (
                SELECT clientid
                FROM clientsettings
                WHERE active = 1
                )
    )
    
    1. “如果它可以通过存储过程总计,使用”周回来“int,那将是整整几周,然后(wishlist项目)总计当前这周的数据,这将是完美的。这是可能的鉴于以下情况?即exec spGetTotalsWeeksBack 8,将在8周前看,总计只有整整一周“
    2. 我想你可以做GROUP BY (DATEDIFF(week, @reportStartDate, RecordCreateDate之类的事情然后PIVOT-ing结果。

      虽然,我担心你无法避免对于Week0-WeekN列的动态sql。