对表的所有列的SQL操作

时间:2014-09-17 13:43:28

标签: sql

我在一个表中有很多(> 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

我想知道是否有一种更聪明的方法可以做到这一点,或者在一个步骤中将它们创建为表中的新列,或者可能转动数据,对其执行某些操作以及重新转动?

1 个答案:

答案 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