我有一个数据库表,如下所示,有超过100000条记录:
我正在尝试对此实施汇总查询,以便我可以检索特定项目的记录并按月显示数量。
我有超过100000条记录,有15列。目前,它基于按年和月的迭代选择查询来检索以计算总和。我想使用汇总来加速检索。
答案 0 :(得分:1)
您只需要进行条件聚合:
DECLARE @fromYear INT = 2010,
@toYear INT = 2014
DECLARE @fromDate DATE,
@toDate DATE
-- Generate date range based on @fromYear and @toYear
SELECT
@fromDate = DATEADD(YEAR, @fromYear - 1900, 0),
@toDate = DATEADD(YEAR, @toYear - 1900 + 1, 0)
SELECT
YEAR(soldDate),
[Jan] = SUM(CASE WHEN MONTH(soldDate) = 1 THEN quantity ELSE 0 END),
[Feb] = SUM(CASE WHEN MONTH(soldDate) = 2 THEN quantity ELSE 0 END),
[Mar] = SUM(CASE WHEN MONTH(soldDate) = 3 THEN quantity ELSE 0 END),
[Apr] = SUM(CASE WHEN MONTH(soldDate) = 4 THEN quantity ELSE 0 END),
[May] = SUM(CASE WHEN MONTH(soldDate) = 5 THEN quantity ELSE 0 END),
[Jun] = SUM(CASE WHEN MONTH(soldDate) = 6 THEN quantity ELSE 0 END),
[Jul] = SUM(CASE WHEN MONTH(soldDate) = 7 THEN quantity ELSE 0 END),
[Aug] = SUM(CASE WHEN MONTH(soldDate) = 8 THEN quantity ELSE 0 END),
[Sep] = SUM(CASE WHEN MONTH(soldDate) = 9 THEN quantity ELSE 0 END),
[Oct] = SUM(CASE WHEN MONTH(soldDate) = 10 THEN quantity ELSE 0 END),
[Nov] = SUM(CASE WHEN MONTH(soldDate) = 11 THEN quantity ELSE 0 END),
[Dec] = SUM(CASE WHEN MONTH(soldDate) = 12 THEN quantity ELSE 0 END)
FROM tbl
WHERE
item = 'basketball'
AND soldDate >= @fromDate
AND soldDate < @toDate
GROUP BY YEAR(soldDate)
如果您想要显示所有年份,包括那些包含0件商品的年份,您需要先生成所有这些年份。你可以使用计数表来做到这一点。然后,结果将LEFT JOIN
添加到上面的原始查询:
DECLARE @fromYear INT = 2010,
@toYear INT = 2014
DECLARE @fromDate DATE,
@toDate DATE
-- Generate date range based on @fromYear and @toYear
SELECT
@fromDate = DATEADD(YEAR, @fromYear - 1900, 0),
@toDate = DATEADD(YEAR, @toYear - 1900 + 1, 0)
;WITH E1(N) AS(
SELECT 1 FROM(VALUES (1),(1),(1),(1),(1),(1),(1),(1),(1),(1))t(N)
),
E2(N) AS(SELECT 1 FROM E1 a CROSS JOIN E1 b),
E4(N) AS(SELECT 1 FROM E2 a CROSS JOIN E2 b),
CteTally(N) AS(
SELECT TOP(@toYear - @fromYear)
ROW_NUMBER() OVER(ORDER BY(SELECT NULL))
FROM E4
),
CteAgg AS(
SELECT
[Yr] = YEAR(soldDate),
[Jan] = SUM(CASE WHEN MONTH(soldDate) = 1 THEN quantity ELSE 0 END),
[Feb] = SUM(CASE WHEN MONTH(soldDate) = 2 THEN quantity ELSE 0 END),
[Mar] = SUM(CASE WHEN MONTH(soldDate) = 3 THEN quantity ELSE 0 END),
[Apr] = SUM(CASE WHEN MONTH(soldDate) = 4 THEN quantity ELSE 0 END),
[May] = SUM(CASE WHEN MONTH(soldDate) = 5 THEN quantity ELSE 0 END),
[Jun] = SUM(CASE WHEN MONTH(soldDate) = 6 THEN quantity ELSE 0 END),
[Jul] = SUM(CASE WHEN MONTH(soldDate) = 7 THEN quantity ELSE 0 END),
[Aug] = SUM(CASE WHEN MONTH(soldDate) = 8 THEN quantity ELSE 0 END),
[Sep] = SUM(CASE WHEN MONTH(soldDate) = 9 THEN quantity ELSE 0 END),
[Oct] = SUM(CASE WHEN MONTH(soldDate) = 10 THEN quantity ELSE 0 END),
[Nov] = SUM(CASE WHEN MONTH(soldDate) = 11 THEN quantity ELSE 0 END),
[Dec] = SUM(CASE WHEN MONTH(soldDate) = 12 THEN quantity ELSE 0 END)
FROM tbl t
WHERE
item = 'basketball'
AND soldDate >= @fromDate
AND soldDate < @toDate
GROUP BY YEAR(soldDate)
)
SELECT
[Yr] = (@fromYear + t.N - 1),
[Jan] = ISNULL([Jan], 0),
[Feb] = ISNULL([Feb], 0),
[Mar] = ISNULL([Mar], 0),
[Apr] = ISNULL([Apr], 0),
[May] = ISNULL([May], 0),
[Jun] = ISNULL([Jun], 0),
[Jul] = ISNULL([Jul], 0),
[Aug] = ISNULL([Aug], 0),
[Sep] = ISNULL([Sep], 0),
[Oct] = ISNULL([Oct], 0),
[Nov] = ISNULL([Nov], 0),
[Dec] = ISNULL([Dec], 0)
FROM CteTally t
LEFT JOIN CteAgg a
ON (@fromYear + t.N - 1) = a.Yr
ORDER BY (@fromYear + t.N - 1)
DROP TABLE tbl