sql:将行的值作为列 [英] sql: values of rows as columns

查看:306
本文介绍了sql:将行的值作为列的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一张桌子,我在其中存储合同的交易,如下所示:

I have got a table where i store transactions for contracts like so:

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中选择一个时间跨度,他会得到结果:

The user should be able to chose the timespan of the query what i want to archive is that if the user chooses a timespan from 01/2012 - 03-2012 he gets the result:

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

您对我如何解决这个问题有任何建议吗?

Do you have any suggestions how i could solve this?

最诚挚的问候, r3try

Best regards, r3try

非常感谢您的答复! 当我搜寻我的问题时,我也偶然发现了旋转问题,但是到目前为止,我还没有找到一个可以真正解决我问题的示例(因为基本上每个示例都为列条目提供了特定的可能性,但是在我的示例中,它可能像是'2012年3月','2012年4月',...,'2013年1月',...)

THANKS FOR THE ANSWERS SO FAR! When i googled for my problem i also stumbled across pivoting, but i havent found an example so far that really solves my issue (because basically every example gives the specific possibilities for the column entries, but in my example it can be like 'March 2012', 'April 2012', ..., 'January 2013', ...)

只是给你们一些有关我打算如何处理我从sql查询中获取的日期的背景信息: 我有一个带有Gridview的asp.net Webforms网站,其中包含一些合同数据...现在,该表应通过该特定合同的付款信息进行扩展(基本上是Id_Contract上的联接,但已透视"). 如果用户选择2012年3月至2012年5月,则Gridview应包含合同上的常规数据+ 3列付款信息列(3月,4月,5月). 在数据库中,仅存储已具有插入值的条目. ->我希望解释能使事情变得更清楚.

Just to give you guys some more background info on what im planning to do with the date i got from the sql query: I have got an asp.net webforms site with a gridview that contains some data on contracts... now this table should be expanded by the payment information on that specific contract (basically a join on Id_Contract but 'pivoted'). If the user chooses March 2012 - May 2012 the Gridview should contain the normal data on the contract + 3 columns on payment information (March, April, May). In the DB there are only entries stored which have already an inserted value. -> i hope that explanation makes things a little bit clearer.

推荐答案

可以使用动态透视"解决您的问题.请查看此

Your problem can be solve using Dynamic Pivoting. Please look into this 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

让我知道它是否满足要求.

Let me know if it satisfies the requirement.

这篇关于sql:将行的值作为列的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆