我在数据库中有这样的数据
INPUT
Id | Start Date | End Date | Value
1 1/2/2010 1/6/2010 20
2 1/5/2010 1/7/2010 80
我需要像这样使用SQL查询来转换这些数据
输出
Id | Month | Value
1 1/2/2010 20
1 1/3/2010 20
1 1/4/2010 20
1 1/5/2010 20
1 1/6/2010 20
2 1/5/2010 80
2 1/6/2010 80
2 1/7/2010 80
请建议可能的解决方案。考虑性能,因为输入表有数百万条记录,我们需要处理所有记录。我正在使用SQL 2008,并希望避免循环或游标。感谢。
答案 0 :(得分:1)
然后看一下使用递归CTE查询。
像
这样的东西DECLARE @Table TABLE(
Id INT,
StartDate DATETIME,
EndDate DATETIME,
Value FLOAT
)
INSERT INTO @Table SELECT 1,'1/2/2010','1/6/2010',20
INSERT INTO @Table SELECT 2,'1/5/2010','1/7/2010',80
;WITH Vals AS (
SELECT id,
StartDate,
EndDate,
Value
FROM @Table
UNION ALL
SELECT id,
StartDate + 1,
EndDate,
Value
FROM Vals
WHERE StartDate + 1 <= EndDate
)
SELECT *
FROM Vals
ORDER BY id,
StartDate
OPTION (MAXRECURSION 0)
答案 1 :(得分:0)
看到这个问题: Get a list of dates between two dates using a function
您可以在接受的答案中使用explosionates函数,并从中构建您的透视结果。
答案 2 :(得分:0)
创建帮助程序表Beta:
CREATE TABLE Beta (
Monat DATETIME,
)
用你需要的所有monthes填充它:
INSERT INTO Beta VALUES( '1/1/2010' )
...
INSERT INTO Beta VALUES( '1/12/2010' ) ' maybe '12/1/2010'
和
SELECT A.Id, B.Monat, A.Value
FROM <YourTable> A, Beta B
WHERE B.Monat >= A.StartDate And B.Monat <= A.EndDate
(没有保证表现)
我没想到像这样的东西必须被'证明' -
===============================================================================
SO5192555 - select for hungryMind
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
SELECT * FROM Alpha
-------------------------------------------------------------------------------
|Id|StartDate|EndDate |Value|
| 1| 2/1/2010|6/1/2010| 20|
| 2| 5/1/2010|7/1/2010| 80|
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
SELECT A.Id, B.Monat, A.Value FROM Alpha A, Beta B WHERE B.Monat >= A.StartDate And B.Monat <= A.EndDate
-------------------------------------------------------------------------------
|Id|Monat |Value|
| 1|2/1/2010| 20|
| 1|3/1/2010| 20|
| 1|4/1/2010| 20|
| 1|5/1/2010| 20|
| 1|6/1/2010| 20|
| 2|5/1/2010| 80|
| 2|6/1/2010| 80|
| 2|7/1/2010| 80|
===============================================================================
xpladolib.vbs: Erfolgreich beendet. (0) [ 0.17969 secs ]
答案 3 :(得分:0)
尽管饿了,我的“我不能”和“似乎”,我仍然认为使用帮手 桌子是正确的方法:
填写表Alpha,其中包含50.000条记录,如
SELECT TOP 5 *, DATEDIFF("d", StartDate, EndDate ) + 1 AS Days FROM Alpha ORDER BY Id
-------------------------------------------------------------------------------
|Id|StartDate |EndDate |Value|Days|
| 1| 12/6/2001| 5/15/2002| 10| 161|
| 2| 8/2/2001 |10/27/2001| 20| 87|
| 3|10/28/2000| 6/17/2001| 30| 233|
| 4| 1/15/2000| 8/30/2000| 40| 229|
| 5| 3/25/2002|10/23/2002| 50| 213|
-------------------------------------------------------------------------------
SELECT TOP 5 *, DATEDIFF("d", StartDate, EndDate ) + 1 AS Days FROM Alpha ORDER BY Id DESC
-------------------------------------------------------------------------------
|Id |StartDate |EndDate |Value |Days|
|50000|10/31/2001| 5/6/2002 |500000| 188|
|49999| 8/31/2002|12/31/2002|499990| 123|
|49998| 4/11/2002|11/11/2002|499980| 215|
|49997| 3/13/2002|12/16/2002|499970| 279|
|49996| 7/4/2002 | 7/27/2002|499960| 24|
并根据MIN(StartDate)范围创建辅助表Beta ... MAX(EndDate) - 我使用循环插入所有1297天 -
-----------------------------------------------
SELECT TOP 5 * FROM Beta ORDER BY Monat
-----------------------------------------------
|Monat |
|1/1/2000|
|1/2/2000|
|1/3/2000|
|1/4/2000|
|1/5/2000|
-----------------------------------------------
SELECT TOP 5 * FROM Beta ORDER BY Monat DESC
-----------------------------------------------
|Monat |
|7/20/2003|
|7/19/2003|
|7/18/2003|
|7/17/2003|
|7/16/2003|
并执行
SELECT A.Id, B.Monat, A.Value
INTO Gamma FROM Alpha A, Beta B
WHERE B.Monat >= A.StartDate And B.Monat <= A.E
将7.522.243条记录插入表格Gamma:
SELECT TOP 5 * FROM Gamma Order BY Id, Monat
-----------------------------------------------------------
|Id|Monat |Value|
| 1| 12/6/2001| 10| <--- | 1| 12/6/2001| 5/15/2002| 10| 161|
| 1| 12/7/2001| 10|
| 1| 12/8/2001| 10|
| 1| 12/9/2001| 10|
| 1|12/10/2001| 10|
-----------------------------------------------------------
SELECT TOP 5 * FROM Gamma Order BY Id DESC, Monat
-----------------------------------------------------------
|Id |Monat |Value |
|50000|10/31/2001|500000| <---- |50000|10/31/2001| 5/6/2002 |500000| 188|
|50000| 11/1/2001|500000|
|50000| 11/2/2001|500000|
|50000| 11/3/2001|500000|
|50000| 11/4/2001|500000|
在我的WinXP / SQLExpress / 1 GB Mem / VirtualBox机器上花了大约2分钟。干 只是“SELECT INTO”花了26秒。
50.000源记录小于113000或'百万',但我做了我的测试 通过VBScript使用ADO / OleDB。当然,MS Server Admin可以做得更好。