使用Transact SQL选择运行总图的数据

时间:2013-04-29 04:13:38

标签: sql sql-server tsql graph running-total

我有一个包含以下结构的表格: AuthorId,FollowersNumber,PublishDate,... 我需要的是按周期绘制一系列FollowersNumber的图表。棘手的是每个作者只计算一次。例如,下表:

AuthorId, FollowersNumber, PublishDate
1         100              '2013-01-01'
2         200              '2013-01-01'
3         200              '2013-01-02'
2         100              '2013-01-02'
4          60              '2013-01-03'
1          30              '2013-01-03'

结果必须是:

2013-01-01 - 300 (100+200)
2013-01-02 - 500 (300+200)
2013-01-03 - 560 (500+60)

现在我的SQL看起来像(简化):

SELECT 0, SUM (q.FollowersNumber) AS Y FROM 
(SELECT FollowersNumber FROM dbo.Aggregate p WITH (NOLOCK) WHERE p.PublishDate BETWEEN @CurrentPeriod_0_Start AND @CurrentPeriod_0_End AND p.AuthorId not IN 
(SELECT AuthorId FROM dbo.Aggregate WITH (NOLOCK) WHERE PublishDate BETWEEN @PreviousPeriod_0_Start AND @PreviousPeriod_0_End)) AS q 
UNION
SELECT 1, SUM (q.FollowersNumber) AS Y FROM 
(SELECT FollowersNumber FROM dbo.Aggregate p WITH (NOLOCK) WHERE p.PublishDate BETWEEN @CurrentPeriod_1_Start AND @CurrentPeriod_1_End AND p.AuthorId not IN 
(SELECT AuthorId FROM dbo.Aggregate WITH (NOLOCK) WHERE PublishDate BETWEEN @PreviousPeriod_1_Start AND @PreviousPeriod_1_End)) AS q 
etc.

获取该数据后,我计算C#代码中的FollowersNumber总数。 这个查询是怪异的,运行缓慢。 有没有办法让它更快?

4 个答案:

答案 0 :(得分:0)

http://sqlfiddle.com/#!3/ff2cf/4

获取总计历史日期。我不明白你的查询参数

答案 1 :(得分:0)

这可能对你有所帮助 -

DECLARE @temp TABLE
(
      AuthorId INT
    , FollowersNumber INT
    , PublishDate DATETIME
)

INSERT INTO @temp (AuthorId, FollowersNumber, PublishDate)
VALUES 
    (1, 100, '20130101'),
    (2, 200, '20130101'),
    (3, 200, '20130102'),
    (2, 100, '20130102'),
    (4,  60, '20130103'),
    (1,  30, '20130103')

DECLARE 
      @CurrentPeriod_0_Start DATETIME
    , @PreviousPeriod_0_Start DATETIME
    , @CurrentPeriod_0_End DATETIME
    , @PreviousPeriod_0_End DATETIME
    , @CurrentPeriod_1_Start DATETIME
    , @PreviousPeriod_1_Start DATETIME
    , @CurrentPeriod_1_End DATETIME
    , @PreviousPeriod_1_End DATETIME


SELECT 0, Y = SUM(p.FollowersNumber) 
FROM @temp p 
WHERE p.PublishDate BETWEEN @CurrentPeriod_0_Start AND @CurrentPeriod_0_End 
    AND NOT EXISTS(
        SELECT 1
        FROM @temp p2
        WHERE p2.PublishDate BETWEEN @PreviousPeriod_0_Start AND @PreviousPeriod_0_End
            AND p2.AuthorId = p.AuthorId

    )

UNION ALL

SELECT 1, Y = SUM(p.FollowersNumber)  
FROM @temp p 
WHERE p.PublishDate BETWEEN @CurrentPeriod_1_Start AND @CurrentPeriod_1_End 
    AND NOT EXISTS(
        SELECT 1
        FROM @temp p2
        WHERE p2.PublishDate BETWEEN @PreviousPeriod_1_Start AND @PreviousPeriod_1_End
            AND p2.AuthorId = p.AuthorId

    )

答案 2 :(得分:0)

您可以使用此查询而不是您的查询。 我在SQL Server中使用CTE编写了此查询。我在你的数据样本上测试过它并且工作正常。

WITH 
RANKINGTABLE AS(
          SELECT [AUTHORID]
              ,[FOLLOWERSNUMBER]
              ,[PUBLISHDATE]
              ,DENSE_RANK() OVER(PARTITION BY AUTHORID ORDER BY PUBLISHDATE) IRANK 
          FROM [TESTQUERY].[DBO].[AGGREGATE]
          ),
DAYSUM AS(
SELECT PUBLISHDATE, SUM([FOLLOWERSNUMBER]) DATESUM 
FROM RANKINGTABLE 
WHERE IRANK = 1
GROUP BY PUBLISHDATE
)
SELECT DS1.PUBLISHDATE, 
        (SELECT SUM(DS2.DATESUM) FROM DAYSUM DS2 WHERE DS2.PUBLISHDATE <= DS1.PUBLISHDATE) PTOTAL  
FROM DAYSUM DS1 

答案 3 :(得分:0)

你可以试试这个

SELECT 1, SUM(CASE WHEN PublishDate BETWEEN @PreviousPeriod_0_Start AND @PreviousPeriod_0_End
                   THEN NULL ELSE CASE WHEN PublishDate BETWEEN @CurrentPeriod_0_Start AND @CurrentPeriod_0_End
                                       THEN FollowersNumber
                                  END
                   END
              ) AS Y
FROM dbo.Aggregate WITH(NOLOCK)
UNION ALL
SELECT 0, SUM(CASE WHEN PublishDate BETWEEN @PreviousPeriod_1_Start AND @PreviousPeriod_1_End
                   THEN NULL ELSE CASE WHEN PublishDate BETWEEN @CurrentPeriod_1_Start AND @CurrentPeriod_1_End
                                       THEN FollowersNumber
                                  END
                   END
              ) AS Y
FROM dbo.Aggregate WITH(NOLOCK)
etc.