【问题标题】:Regarding SQL Pivot关于 SQL Pivot
【发布时间】:2018-10-22 11:10:06
【问题描述】:

您好,我一直在尝试对以下数据进行 PIVOT。

LeaseId | ColumnHeader  | UIPayments | UIResidual
-------------------------------------------------
25573   | 2019-05-01    | 0.0000     | 0.0000    
25573   | 2019-06-01    | 0.0000     | 0.0000    
25573   | 2019-07-01    | 0.0000     | 0.0000    
25573   | 2019-08-01    | 0.0000     | 0.0000    
25573   | 2019-09-01    | 0.0000     | 0.0000    
25573   | 2019-10-01    | 0.0000     | 0.0000   

结果数据集应如下所示:

LeaseId |Details    | 2019-05-01| 2019-06-01|2019-07-01 |2019-08-01
-----------------------------------------------------------------                
25573   |UIPayments |5.0000     |5.0000     |5.0000     |5.0000

25573   |UIResidual |1.0000     |1.0000     |1.0000     |1.0000

有可能吗?

提前致谢。

到目前为止我尝试过的查询:

DECLARE @cols AS NVARCHAR(MAX),
@query  AS NVARCHAR(MAX)

select @cols = STUFF((SELECT ',[' + CAST(DATEFROMPARTS(#TempMonths.y, #TempMonths.m, '01') AS VARCHAR(20)) + ']'
                from #TempMonths
        FOR XML PATH(''), TYPE
        ).value('.', 'NVARCHAR(MAX)') 
    ,1,1,'')

set @query = 'SELECT LeaseID, UIPayments, UIResidual, PVResidual, PVPayments, NetInvestment,' + @cols + ' from 
         (
            SELECT * FROM #TmpDetails
        ) x
        pivot 
        (
            UIPayments, UIResidual, PVResidual, PVPayments, NetInvestment
            for ColumnHeader in (' + @cols + ')
        ) p '

我真的不知道这是否是一个有效的查询。

提前致谢!

【问题讨论】:

  • 您使用的是哪个 dbms?
  • 这是什么逻辑,到目前为止你尝试了什么..?
  • 知道 确定这些是你想要的最后一列/需要?或者你想让列由数据中存在的值定义?如果是这样,这在 SQL 中几乎不是一件好事:它很混乱并且违反了大多数 SQL 模式(通常最好将格式保存在“表示层”中,例如您在其中进行报告的应用程序。如果您准确地解释了您希望如何使用这些数据,以及在哪里,我们可能会为您提供更强大/更合适的解决方案来满足您的实际需求。)
  • 我正在使用 SQL。我无法理解这一点的逻辑,但我会在下面发布我到目前为止所做的事情。关于列,它是动态的。根据输入日期,这些列将在接下来的 2 年内每个月。即如果输入日期是 2018 年 1 月 1 日,那么列将是 2018 年 1 月 1 日、2018 年 2 月 1 日、... 2020 年 1 月 1 日。
  • @Ashwath - 根据我之前的评论。想要这样做通常会违反已建立的 SQL 模式。没有本机 SQL 可以做到这一点。您需要做的是读取表,获取列列表,使用它以编程方式生成新的 sql 语句并运行它。这种复杂程度和开销是一个非常强烈的指标,表明你走错了路。请问我可以再问一次吗?如果您准确说明您希望如何使用这些数据以及在何处使用这些数据,我们可能会为您提供更强大/更合适的解决方案来满足您的实际需求。

标签: sql sql-server pivot dynamic-pivot


【解决方案1】:

条件聚合几乎适用于任何数据库:

select LeaseId, 'UIPayments' as details,
       sum(case when ColumnHeader = '2019-05-01' then UIPayments else 0 end) as val_20190501,
       sum(case when ColumnHeader = '2019-06-01' then UIPayments else 0 end) as val_20190601,
       sum(case when ColumnHeader = '2019-07-01' then UIPayments else 0 end) as val_20190701,
       sum(case when ColumnHeader = '2019-08-01' then UIPayments else 0 end) as val_20190801
from t
group by LeaseId
union all
select LeaseId, 'UIResidual' as details,
       sum(case when ColumnHeader = '2019-05-01' then UIResidual else 0 end) as val_20190501,
       sum(case when ColumnHeader = '2019-06-01' then UIResidual else 0 end) as val_20190601,
       sum(case when ColumnHeader = '2019-07-01' then UIResidual else 0 end) as val_20190701,
       sum(case when ColumnHeader = '2019-08-01' then UIResidual else 0 end) as val_20190801
from t
group by LeaseId;

我想诀窍是您需要分别处理每一列。在许多数据库中,您可以使用横向连接而不是 union all

【讨论】:

  • 但在我的情况下,这些列是动态的。我怎样才能使用这种方法?
  • 你可以把这个`sum(当ColumnHeader = '2019-05-01'然后UIPayments else 0 end)作为val_20190501, sum(case when ColumnHeader = '2019-06-01' then UIPayments else 0 end) as val_20190601, sum(case when ColumnHeader = '2019-07-01' then UIPayments else 0 end) as val_20190701, sum(case when ColumnHeader = '2019-08-01' then UIPayments else 0 end) as val_20190801 ` 这部分动态使用 java 或 .net 代码。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-12-29
  • 2015-12-06
  • 2021-02-03
  • 2013-03-15
  • 1970-01-01
  • 1970-01-01
  • 2021-05-06
相关资源
最近更新 更多