【发布时间】:2012-12-21 10:09:01
【问题描述】:
以下是我两年前开始使用的模式,并且在我的遗留代码中一遍又一遍地重复。
它使用不同的时间段有效地对相同的数据进行分组。
我是否应该采用标准方法来解决这个问题,或者这种冗长的方法是否和我能得到的一样好?
提出这个问题的另一种方式是如何使以下内容更简洁?
所有 4 个查询都来自同一个数据源,并且所有四个查询都进入同一个输出表,这 4 个查询可以合并为 1 个较短的脚本吗?
DECLARE @myDate DATETIME = CONVERT(DATETIME,CONVERT(VARCHAR(11),GETDATE(),106));
DECLARE @myFirstDateLastMth CHAR(8) =CONVERT(CHAR(6),DATEADD(mm,-1,@myDate-1),112) + '01';
DECLARE @myFirstDateCurrentMth CHAR(8) =CONVERT(CHAR(6),DATEADD(mm,0,@myDate-1),112) + '01';
DELETE FROM WH.dbo.tb_myTable
--day on day==========
INSERT INTO WH.dbo.tb_myTable
SELECT
TimePeriod =
CASE
WHEN x.DateKey = CONVERT(VARCHAR(11),@myDate - 1,112) THEN 'Day'
WHEN x.DateKey = CONVERT(VARCHAR(11),@myDate - 2,112) THEN 'Day-1'
END,
Game = x.Name,
Score = SUM(x.Score),
Ticks = SUM(x.Ticks),
ScorePerTick = SUM(x.Score)/SUM(x.Ticks)
FROM #LimitedBetinfo x
WHEREx.DateKey >= CONVERT(VARCHAR(11),@myDate - 2,112)
GROUP BY
CASE
WHEN x.DateKey = CONVERT(VARCHAR(11),@myDate - 1,112) THEN 'Day'
WHEN x.DateKey = CONVERT(VARCHAR(11),@myDate - 2,112) THEN 'Day-1'
END,
x.Name;
--wk on wk==========
INSERT INTO WH.dbo.tb_myTable
SELECT
TimePeriod =
CASE
WHEN x.DateKey >= CONVERT(VARCHAR(11),@myDate - 7,112) THEN 'Week'
WHEN x.DateKey < CONVERT(VARCHAR(11),@myDate - 7,112)
AND x.DateKey >= CONVERT(VARCHAR(11),@myDate - 14,112)
THEN 'Week-1'
END,
Game = x.Name,
Score = SUM(x.Score),
Ticks = SUM(x.Ticks),
ScorePerTick = SUM(x.Score)/SUM(x.Ticks)
FROM #LimitedBetinfo x
WHERE x.DateKey >= CONVERT(VARCHAR(11),@myDate - 14,112)
GROUP BY
CASE
WHEN x.DateKey >= CONVERT(VARCHAR(11),@myDate - 7,112) THEN 'Week'
WHEN x.DateKey < CONVERT(VARCHAR(11),@myDate - 7,112)
AND x.DateKey >= CONVERT(VARCHAR(11),@myDate - 14,112)
THEN 'Week-1'
END,
g.Name;
--mth on mth==========
INSERT INTO WH.dbo.tb_myTable
SELECT
TimePeriod =
CASE
WHEN x.DateKey >= CONVERT(VARCHAR(11),@myDate - 28,112) THEN 'Month'
WHEN x.DateKey < CONVERT(VARCHAR(11),@myDate - 28,112)
AND x.DateKey >= CONVERT(VARCHAR(11),@myDate - 56,112)
THEN 'Month-1'
END,
Game = x.Name,
Score = SUM(x.Score),
Ticks = SUM(x.Ticks),
ScorePerTick = SUM(x.Score)/SUM(x.Ticks)
FROM #LimitedBetinfo x
WHERE x.DateKey >= CONVERT(VARCHAR(11),@myDate - 56,112)
GROUP BY
CASE
WHEN x.DateKey >= CONVERT(VARCHAR(11),@myDate - 28,112) THEN 'Month'
WHEN x.DateKey < CONVERT(VARCHAR(11),@myDate - 28,112)
AND x.DateKey >= CONVERT(VARCHAR(11),@myDate - 56,112)
THEN 'Month-1'
END,
g.Name;
--MTD and PrevCalMonth==========
INSERT INTO WH.dbo.tb_myTable
SELECT
TimePeriod
= CASE
WHEN x.DateKey >= @myFirstDateCurrentMth THEN 'MTD'
WHEN x.DateKey < @myFirstDateCurrentMth
AND x.DateKey >=@myFirstDateLastMth THEN 'PrevCalMonth'
END,
Game = x.Name,
Score = SUM(x.Score),
Ticks = SUM(x.Ticks),
ScorePerTick = SUM(x.Score)/SUM(x.Ticks)
FROM #LimitedBetinfo x
WHERE x.DateKey >= CONVERT(CHAR(6),DATEADD(mm,-1,@myDate-1),112) + '01'
GROUP BY
CASE
WHEN x.DateKey >= @myFirstDateCurrentMth THEN 'MTD'
WHEN x.DateKey < @myFirstDateCurrentMth
AND x.DateKey >=@myFirstDateLastMth THEN 'PrevCalMonth'
END,
g.Name;
【问题讨论】:
-
DateKey 的数据类型是什么? datetime 还是 varchar ?
-
你能详细说明你到底想要什么吗?除非我遗漏了一些东西
GROUP BY DAY(Date)和GROUP BY MONTH(Date)应该让你朝着你的目标前进 50%。 -
@Dukeling - 目前有四个脚本;所有这些的输入数据是相同的;它们的输出表都是相同的.....这四个脚本可以合并到一个脚本/过程中吗?我在大约 10 个生产存储过程中使用了类似这 4 个的东西,因此缩短这个示例将使我的遗留代码更短。弗雷德的回答很好。
标签: sql sql-server design-patterns sql-server-2008-r2