rka (9/3/2012)
Has anyone done any similar SQL Script to generate this?
Quite possibly thousands of times. 😀
The first thing you need is the Swiss Army Knife for T-SQL known as a Tally Table. It has hundreds of uses and this is one of them. Please see the following article for what a Tally Table is and how it can be used to replace certain WHILE loops with incredible performance.
http://www.sqlservercentral.com/articles/T-SQL/62867/
Here's how to build a "unit based" Tally Table.
--===== Do this in a nice safe place that everyone has
-- (You can build a permanent one in any database)
USE TempDB;
IF OBJECT_ID('TempDB..Tally','U') IS NOT NULL
DROP TABLE Tally;
GO
--===================================================================
-- Create a Tally table from 1 to 11000
--===================================================================
--===== Create and populate the Tally table on the fly.
SELECT TOP 11000
IDENTITY(INT,1,1) AS N
INTO dbo.Tally
FROM Master.sys.ALL_Columns ac1
CROSS JOIN Master.sys.ALL_Columns ac2
;
--===== Add a CLUSTERED Primary Key to maximize performance
ALTER TABLE dbo.Tally
ADD CONSTRAINT PK_Tally_N
PRIMARY KEY CLUSTERED (N) WITH FILLFACTOR = 100
;
--===== Allow the general public to use it
GRANT SELECT ON dbo.Tally TO PUBLIC
;
GO
After that, the Tally Table makes your problem easy to solve with a little help from some date/time functions and a CROSS JOIN...
--===== Conditionally drop the test table to make reruns in SSMS easier.
-- This is just a test table and is not a part of the solution.
IF OBJECT_ID('tempdb..#YourTable','U') IS NOT NULL
DROP TABLE #YourTable
;
--===== Create the test table.
-- This is just a test table and is not a part of the solution.
CREATE TABLE #YourTable
(
YearMonth INT,
[Value] INT
)
;
--===== Populate the table with test data.
-- This is just test data and is not a part of the solution.
INSERT INTO #YourTable
(YearMonth,[Value])
SELECT 201207,5000 UNION ALL
SELECT 201208,4000 UNION ALL
SELECT 201201,3100 UNION ALL
SELECT 200002,2900
;
--===== Solve the problem.
SELECT YearMonth,
[Day] = CONVERT(CHAR(10),DATEADD(mm,((YearMonth/100)-1900)*12 + YearMonth%100-1,0)+(t.N-1),103),
[Value] = ([Value]+0.0)/DAY(DATEADD(mm,((YearMonth/100)-1900)*12 + YearMonth%100,0)-1)
FROM #YourTable
CROSS JOIN dbo.Tally t
WHERE t.N <= DAY(DATEADD(mm,((YearMonth/100)-1900)*12 + YearMonth%100,0)-1)
ORDER BY YearMonth, t.N
;
--Jeff Moden
Change is inevitable... Change for the better is not.