当前位置: 首页 > 面试题库 >

sql:将行的值作为列

白弘伟
2023-03-14
问题内容

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

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查询中获取日期的背景信息:我有一个asp.net
Webforms网站,其gridview包含一些合同数据…现在此表应该通过该特定合同的付款信息进行扩展(基本上是Id_Contract上的联接,但已“枢纽化”)。如果用户选择2012年3月至2012年5月,则Gridview应包含合同上的常规数据+
3列付款信息列(3月,4月,5月)。在数据库中,仅存储已具有插入值的条目。->我希望解释能使事情变得更清楚。


问题答案:

您可以使用“动态旋转”解决问题。请看这篇文章

试试这个

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

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



 类似资料:
  • 问题内容: 我在C#方面非常有经验,但是仍然还是SQL的初学者。 我们有一个使用MSSQL数据库的C#应用​​程序。 我们的应用程序的一部分只是简单地编写一系列预查询,作为报告,通过简单地运行查询并将返回的表粘贴到gridView即可显示该报告。用户正在请求一个新的报表,我不能完全确定仅使用SQL还是可以的,并且需要对返回的数据进行处理才能使其看起来正确。 用户想要的数据(以他们希望的方式呈现)将

  • 我有一个单行数据帧,如下所示 我想得到一个像下面这样的数据帧 这里的逻辑是a。将有3个包含TP/VR/TV的列名。所以在ID中,我们有1,2 我尝试了df.filter(regex='TP').stack()。我得到了所有的“TP”栏 我还想知道是否有更简单的方法来做到这一点。

  • 问题内容: 我有桌子: 我想要这样的输出: 问题答案: 如果可以创建一个数字表,其中包含从1到要拆分的最大字段的数字,则可以使用以下解决方案: 请看这里的小提琴。 如果无法创建表,则解决方案可以是: 这里有个小提琴例子。

  • 我有表: 我想要这样的输出:

  • 问题内容: 我有一个以下格式的表格 我想将其转换为以下格式 如何通过sql查询或sql服务器程序集实现此目的? 问题答案: 您可以完成。如果您知道已知的列数,则可以对值进行硬编码: 参见带有演示的SQL Fiddle 如果列数未知,则可以使用动态sql: 参见带有演示的SQL Fiddle 您甚至可以使用:

  • 问题内容: 我有一个SQL查询返回1行,其中包含多个列标题: 有没有一种方法可以将该行转换为2列,即: 这是在SQLServer 2008 r2上运行 编辑:添加一个更好的例子 来自一个简单的 类型查询。我要显示的是: 问题答案: 试试这个