使用 Rollup 从 SQL 服务器中的 mm/dd/yyyy 获取每月和每年的计数值
Get monthy and yearly count value from mm/dd/yyyy in SQL Server using Rollup
我有一个数据库 table,如下所示,有超过 100000 条记录:
我正在尝试对此实施汇总查询,以便我可以检索特定项目的记录并按月显示数量。
我有 15 列的超过 100000 条记录。目前它是基于 select 查询迭代检索按年然后按月计算总和。我想用rollup来加快检索速度。
你只需要做条件聚合:
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 件商品的年份,你需要先生成所有这些年份。您可以使用计数 table 来做到这一点。然后结果将 LEFT JOIN
ed 到上面的原始查询:
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
我有一个数据库 table,如下所示,有超过 100000 条记录:
我正在尝试对此实施汇总查询,以便我可以检索特定项目的记录并按月显示数量。
我有 15 列的超过 100000 条记录。目前它是基于 select 查询迭代检索按年然后按月计算总和。我想用rollup来加快检索速度。
你只需要做条件聚合:
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 件商品的年份,你需要先生成所有这些年份。您可以使用计数 table 来做到这一点。然后结果将 LEFT JOIN
ed 到上面的原始查询:
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