我在一个表中有很多(> 48个)列,每列对应一个月并包含该月的销售额。我需要创建另一个表,其中每列等于前12列的添加,例如获得"滚动的一年"图,所以,例如2010年7月增加了从2009年8月到2010年7月的所有内容,2010年8月有从2009年9月到2010年8月的所有内容,依此类推。
我可以写成:
select
[201007TOTAL] = [200908] + [200909] + ... + [201007]
,[201008TOTAL] = [200909] + ... + [201008]
...
...
into #newtable
from #mytable
我想知道是否有一种更聪明的方法可以做到这一点,或者在一个步骤中将它们创建为表中的新列,或者可能转动数据,对其执行某些操作以及重新转动?
答案 0 :(得分:0)
尽管每个人都是对的,不同的数据库设置会是最好的,我认为这是一个很好的问题。这是我的设置:
CREATE TABLE TEST
(
ID INT
, [201401] decimal(19, 5)
, [201402] decimal(19, 5)
, [201403] decimal(19, 5)
, [201404] decimal(19, 5)
, [201405] decimal(19, 5)
, [201406] decimal(19, 5)
, [201407] decimal(19, 5)
)
INSERT INTO TEST
VALUES (1, 1, 2, 3, 4, 5, 6, 7)
只有一条包含数据的记录足以进行测试。
假设要求的列在表中是连续的,第一个是第一个数据类型为十进制的。换句话说,表'开始'(为了更好的单词)与PK,通常是INT,可以跟随描述或其他,然后是每月列总和:
DECLARE @OP_START INT
, @OP_END INT
, @LOOP INT
, @DATE VARCHAR(255)
, @SQL VARCHAR(MAX) = 'SELECT '
, @COLNAME VARCHAR(MAX)
-- Set Date to max date (=columnname)
SET @DATE = '201406'
-- Find Last attribute
SET @OP_END = (
SELECT MAX(ORDINAL_POSITION)
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'TEST'
AND COLUMN_NAME <= @DATE
)
-- Find First attribute
SET @OP_START = (
SELECT MIN(ORDINAL_POSITION)
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'TEST'
AND DATA_TYPE = 'DECIMAL'
)
SET @LOOP = @OP_START
-- Loop through the columns
WHILE @LOOP <= @OP_END
BEGIN
SET @COLNAME = (
SELECT COLUMN_NAME
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'TEST'
AND ORDINAL_POSITION = @LOOP
)
-- Build SQL with found ColumnName
SET @SQL = @SQL + '[' + @COLNAME + ']' + '+'
SET @LOOP = @LOOP + 1
END
-- Remove last "+"
SET @SQL = SUBSTRING(@SQL, 1, LEN(@SQL) - 1)
-- Complete SQL
SET @SQL = @SQL + ' FROM TEST'
-- Execute
EXEC(@SQL)
无论添加多少,都应该不断累加月度值。只需将最大日期更改为您喜欢的内容。
我不是说这是最好的方式,但这是一种有趣的方式:P