微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

动态使用列值作为列

如何解决动态使用列值作为列

我有一个查询,它使用一堆 case 语句按部门和员工 ID 汇总销售额,并将月份和年份作为列标题。目前,我正在为每个独特的月份和年份使用 Case 语句。我的目标是尝试找到一种更动态的方法来实现相同的结果,而不必为最终出现在 Mnth_Yr 列中的每个新值添加额外的 case 语句。

我尝试使用 PIVOT,但结果是所有的行值都转换为列,而不仅仅是 Mnth_Yr 列。

这是一个数据样本。

enter image description here

这是我想要达到的预期结果。

enter image description here

这是我正在使用的代码

    IF OBJECT_ID('tempdb.dbo.#table_data') IS NOT NULL
    DROP TABLE #table_data
    
    CREATE table #table_data
    ([Division] varchar(15),[Emp_Id] int,[Mnth_Yr] int,[Sales] money)
    
INSERT INTO #table_data
    ([Division],[Emp_Id],[Mnth_Yr],[Sales])
VALUES
    ('northeast',625,202101,310.58),('northeast',627,252.83),('Southeast',158,5871.12),487,1587.58),202102,521.87),870.24),7812.17),202103,564.57),251.61),15780.45),1770.51)
;
----------------------------------------------------------------------

select Division,Emp_Id,SUM(Case When Mnth_Yr = 202101 Then Sales ELSE null END) as "202101",SUM(Case When Mnth_Yr = 202102 Then Sales ELSE null END) as "202102",SUM(Case When Mnth_Yr = 202103 Then Sales ELSE null END) as "202103"

from #table_data
Group by Division,Emp_Id

解决方法

我的目标是尝试找到一种更动态的方法来实现相同的结果,而不必为最终出现在 Mnth_Yr 列中的每个新值添加额外的 case 语句。* -

你有点不能,除非你使用动态 SQL。这是有原因的;数据库表的列就像事物的属性 - 它们不是动态的,如果是动态的,则很难使用。使用您的数据库的其他系统希望您的 Order 表上有诸如 Total、Name、Address 之类的字段。他们真的不知道如何处理本周没有 NumberofItemsFulfilledInFirstWeekOfJan 而下周有的订单。编写支持事物动态属性的系统,一直到人类用户,都是一项艰巨的工作

我建议您希望对数据进行范围划分,而不是提供 202101、202102 的列,而是考虑提供年复一年具有某种意义的固定名称;称它们为 Jan、Feb、Mar .. 使用 where 子句根据当前年份(通过参数或服务器时钟)选择数据,并让其给出“Jan”含义的上下文

如果您不想这样做,那很好 - 但是保持“查询输出的列数不会根据日期或最近发生的事情动态变化”的口头禅有助于开发数据库驱动软件 - 行数应该有所不同,而不是列数。您希望将数据库用作演示工具,而实际上这种旋转操作应该由前端应用程序中的图表软件执行 - 它可以接收可变行数和固定列数并生成网格

如果您对让数据库执行此操作并使您的列无限可变,那么您将需要编写代码来动态生成查询,并运行它,然后使用它 - 这可能是- db 以类似存储过程的方式,或以查询变体数量的前端语言,并将 SQL 字符串连接在一起并运行它,然后输出结果..

..但是没有办法对你的数据库说“使用这个固定的 sql 查询在 x 上透视这个数据,并给我一个今天有 y 个列的结果集,但明天是 z”

,

嗯,这不是上面提到的方法,但它使用 XML 来满足我的需求。

DECLARE @cols NVARCHAR(MAX),@query NVARCHAR(MAX);
SET @cols = STUFF(
                 (
                     SELECT DISTINCT
                            ','+QUOTENAME(c.Mnth_Yr)
                     FROM #table_data c FOR XML PATH(''),TYPE
                 ).value('.','nvarchar(max)'),1,'');
SET @query = 'SELECT Division,Emp_Id,'+@cols+'from (SELECT Division,sum(sales) AS [amount],Mnth_Yr AS [category]
    FROM #table_data
    Group by Division,Mnth_Yr
    )x pivot (max(amount) for category in ('+@cols+')) p';
EXECUTE (@query);

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?