sql:行的值作为列

时间:2012-09-05 10:31:06

标签: sql sql-server-2008 pivot

我有一张表,我可以为这样的合约存储交易:

Id_Contract[int] | Month[DateTime] | Amount[int]
------------------------------------------------
        1          2012-01-01 00:00:00.000      500     
        1          2012-03-01 00:00:00.000      450 
        2          2012-09-01 00:00:00.000      300     
        3          2012-08-01 00:00:00.000      750 

用户应该能够选择查询的时间跨度 我要归档的是,如果用户选择从01/2012 - 03-2012开始的时间跨度,他会得到结果:

Id_Contract[int] | Jan 2012 | Feb 2012 | Mar 2012
--------------------------------------------------
    1                   500                       450

你有什么建议我能解决这个问题吗?

祝你好运, r3try

编辑:感谢所有的答案! 当我搜索我的问题时,我也偶然发现了旋转,但到目前为止我还没有找到一个真正解决我问题的例子(因为基本上每个例子都给出了列条目的具体可能性,但在我的例子中它可能就像'2012年3月','2012年4月',......,'2013年1月',...)

只是为了给你们一些关于我计划如何处理sql查询日期的背景信息: 我有一个带有gridview的asp.net webforms网站,其中包含有关合同的一些数据......现在这个表应该通过该特定合同的支付信息进行扩展(基本上是Id_Contract上的连接,但是'已转动')。 如果用户选择2012年3月 - 2012年5月,Gridview应包含合同上的正常数据+ 3列付款信息(3月,4月,5月)。 在DB中,只存储已经插入值的条目。 - >我希望这些解释会让事情变得更加清晰。

2 个答案:

答案 0 :(得分:3)

使用动态旋转可以解决您的问题。请查看此article

试试这个

DECLARE @t TABLE(Id_Contract INT, Dt DATETIME,Amount INT)
INSERT INTO @t SELECT 1,'2012-01-01 00:00:00.000',500
INSERT INTO @t SELECT 1,'2012-03-01 00:00:00.000',450
INSERT INTO @t SELECT 2,'2012-09-01 00:00:00.000',300
INSERT INTO @t SELECT 3,'2012-08-01 00:00:00.000',750

DECLARE @cols AS VARCHAR(MAX), @query  AS VARCHAR(MAX);

SELECT 
    Id_Contract
    , LEFT(DATENAME(month,Dt),3) + ' ' + DATENAME(Year,Dt) AS Month_Year_Name
    ,Amount
INTO #Temp
FROM @t 
WHERE Dt BETWEEN  '01/01/2012' AND '03/31/2012'

SELECT  @cols = STUFF(( SELECT DISTINCT 
                               '],[' +   t2.Month_Year_Name
                        FROM    #Temp AS t2
                        ORDER BY '],[' + t2.Month_Year_Name
                        FOR XML PATH('')
                      ), 1, 2, '') + ']'

SET @query = 'SELECT Id_Contract, ' + @cols + ' FROM 
            (
                SELECT
                     Id_Contract
                    , Amount
                    , Month_Year_Name
                FROM #Temp
           ) x
            PIVOT 
            (
                 MAX(amount)
                 FOR Month_Year_Name in (' + @cols + ')
            ) p '
EXECUTE(@query)
DROP TABLE #Temp

//结果

Id_Contract Jan 2012    Mar 2012
1           500         450

修改

对于您的测试数据,

DECLARE @t TABLE(Id_Contract INT, Dt DATETIME,Amount INT) 
INSERT INTO @t SELECT 1,'2012-01-01 00:00:00.000',500 
INSERT INTO @t SELECT 1,'2012-03-01 00:00:00.000',450 
INSERT INTO @t SELECT 2,'2012-03-01 00:00:00.000',450 
INSERT INTO @t SELECT 3,'2012-08-01 00:00:00.000',750 

输出

Id_Contract Jan 2012    Mar 2012
1              500          450
2              NULL         450

如果符合要求,请告诉我。

答案 1 :(得分:0)

您要做的事情称为 pivoting ,并且内置PIVOT and UNPIVOT relational operators.支持它。

我会用解决方案扩展答案,但是现在,看看链接,你会得到一般的想法。