我有一个包含以下结构的表格: 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总数。 这个查询是怪异的,运行缓慢。 有没有办法让它更快?
答案 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.