SQL:行作为列的值(sql: values of rows as columns)

2019-07-31 09:07发布

我有在那里我存储的交易,像这样的合同表:

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

编辑:谢谢你的答案为止! 当我用Google搜索我的问题,我也偶然发现旋转,但我还没有发现到目前为止的例子,真正解决了我的问题(因为基本上每个例子给出了列项具体的可能性,但在我的例子也可以像“2012年3月”, '2012年4月',......, '2013年1月',...)

只给你们上什么即时通讯的规划与我从SQL查询中获得的日期做一些更多的背景信息:我有一个asp.net web表单网站与包含在合同的一些数据......现在这个表应该一个gridview通过具体合同上的付款信息进行扩展(基本上是参加上Id_Contract但“摆动”)。 如果用户选择2012年3月 - 2012年5月在GridView应该包含对支付信息(三月,四月,五月)合同+ 3列中的正常数据。 在DB有存储其已经插入值只有条目。 - >我希望解释使事情一点点清晰。

Answer 1:

你的问题可以解决使用动态枢转。 请看看这个文章

试试这个

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

让我知道这是否满足要求。



Answer 2:

你想要做什么是所谓的旋转 ,并且它是由内置的支持PIVOTUNPIVOT关系运算符。 。

我会扩大一个解决答案,但现在,看看链接,你会得到的总体思路。



文章来源: sql: values of rows as columns