2

我有一个具有以下结构的表: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

4 回答 4

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.
于 2013-04-29T10:09:44.243 回答
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

    )
于 2013-04-29T05:30:02.807 回答
0

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

按日期获取总计历史记录。我不明白你在查询中的参数

于 2013-04-29T04:19:47.980 回答
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 
于 2013-04-29T05:53:32.030 回答