Sql 将多行/列透视为一行
我们需要获取多行和多列,并将它们转换为每个键一行。我有一个pivot查询,但它不工作。关于定义不明确的列,我遇到了一些错误' 我们的数据如下所示:Sql 将多行/列透视为一行,sql,pivot,multiple-columns,rows,Sql,Pivot,Multiple Columns,Rows,我们需要获取多行和多列,并将它们转换为每个键一行。我有一个pivot查询,但它不工作。关于定义不明确的列,我遇到了一些错误' 我们的数据如下所示: SECTOR TICKER COMPANY ----------------------------------------------------- 5 ADNT Adient PLC 5 AUTO Autobytel Inc. 5 THRM Gentherm Inc 5
SECTOR TICKER COMPANY
-----------------------------------------------------
5 ADNT Adient PLC
5 AUTO Autobytel Inc.
5 THRM Gentherm Inc
5 ALSN Allison Transmission Holdings, Inc.
5 ALV Autoliv, Inc.
12 HES Hess Corporation
12 AM Antero Midstrm
12 PHX Panhandle Royalty Company
12 NBR Nabors Industries Ltd.
12 AMRC Ameresco, Inc.
sector sector_char ticker company_name rn
------------------------------------------------------------------------
5 |5| ADNT Adient PLC 1
5 |5| AUTO Autobytel Inc. 2
5 |5| THRM Gentherm Inc 3
5 |5| ALSN Allison Transmission Holdings, Inc. 4
5 |5| ALV Autoliv, Inc. 5
12 |12| HES Hess Corporation 1
12 |12| AM Antero Midstrm 2
12 |12| PHX Panhandle Royalty Company 3
12 |12| NBR Nabors Industries Ltd. 4
12 |12| AMRC Ameresco, Inc. 5
我们需要的是每个ID 1行,每个股票代码/公司在不同的列中。因此,输出将如下所示:
5 ADNT Adient PLC AUTO Autobytel Inc. THRM Gentherm Inc........
你明白了。每个ID 1行,每个ID在其自己的列中有一个值。我尝试的查询是:
SELECT sector, ticker, company_name
FROM (SELECT d.sector, d.ticker, v.company_name, ROW_NUMBER() OVER(PARTITION BY d.sector ORDER BY d.sector) rn
FROM template13_ticker_data d, template13_vw v
WHERE d.m_ticker = v.m_ticker)
PIVOT (MAX(sector) AS sector, MAX(ticker) AS ticker, MAX(company_name) AS company_name
FOR (rn) IN (1 AS sector, 2 AS ticker, 3 AS company_name))
ORDER BY sector;
关于数据透视,首先要了解的是,在结果集中选择一列作为数据透视锚点,数据将围绕该轴旋转,这在FOR子句中指定 您只能为单个列透视,但您可以在子查询中或从联接或视图中构造此列作为目标数据查询,OP使用了ROW_NUMBER,但您可以使用任何希望的SQL机制,甚至CASE语句来构建自定义列,以便在数据集中没有可使用的自然列时进行透视 PIVOT将为for列中的每个值创建一列,并为该列提供您指定的聚合函数的值 它有助于可视化构造的记录集,在应用pivot之前,下面的SQL可以重新创建OP提供的数据场景。我在这里使用了表变量来代替OPs表和视图 -添加了扇区字符的模板13股票代码数据 声明@tickerData表 扇区INT, 股票代码CHAR4, m_ticker CHAR4, 扇区_char10 -模板13_vw 声明@公司表 m_ticker CHAR4, 股票代码CHAR4, 公司名称:VARCHAR100 插入@tickerData扇区,股票代码 值5,'ADNT' ,5,“自动” ,5,'THRM' ,5,'ALSN' ,5,'ALV' ,12,“他” ,12,'AM' ,12,'PHX' ,12,'NBR' ,12,'AMRC' 插入@Company ticker,Company\u name 值“ADNT”,“Adient PLC” “汽车公司”、“汽车电池公司” “THRM”和“Gentherm公司” “ALSN”和“Allison Transmission Holdings,Inc.” “阿尔夫”、“奥托立夫公司” “HES”、“Hess公司” “上午”和“中段” “PHX”、“Panhandle特许权公司” ,'NBR','Nabors Industries Ltd.' “AMRC”、“Ameresco公司” -只需重新创建一个与给定数据和查询结构匹配的记录集 更新@tickerData SET m_ticker=ticker 更新@Company SET m_ticker=ticker -填充“扇区字符”以显示多个聚合 更新@tickerData SET sector_char='|'+castsector为varchar+'|' -未经验证的数据证明 选择d.section、d.section\u char、d.ticker、v.company\u name、按d.section超额分配的行数、按d.section订单 来自@tickerData d,@Company v 其中,d.m_ticker=v.m_ticker 轴之前的数据如下所示:
SECTOR TICKER COMPANY
-----------------------------------------------------
5 ADNT Adient PLC
5 AUTO Autobytel Inc.
5 THRM Gentherm Inc
5 ALSN Allison Transmission Holdings, Inc.
5 ALV Autoliv, Inc.
12 HES Hess Corporation
12 AM Antero Midstrm
12 PHX Panhandle Royalty Company
12 NBR Nabors Industries Ltd.
12 AMRC Ameresco, Inc.
sector sector_char ticker company_name rn
------------------------------------------------------------------------
5 |5| ADNT Adient PLC 1
5 |5| AUTO Autobytel Inc. 2
5 |5| THRM Gentherm Inc 3
5 |5| ALSN Allison Transmission Holdings, Inc. 4
5 |5| ALV Autoliv, Inc. 5
12 |12| HES Hess Corporation 1
12 |12| AM Antero Midstrm 2
12 |12| PHX Panhandle Royalty Company 3
12 |12| NBR Nabors Industries Ltd. 4
12 |12| AMRC Ameresco, Inc. 5
现在,可视化您期望的结果子集,以显示我创建的多个列操作的限制,这些列操作将包含在最终输出中
sector sector_char ticker_1 company_1 ticker_2 company_2
-----------------------------------------------------------------------------
5 |5| ADNT Adient PLC AUTO Autobytel Inc.
12 |12| HES Hess Corporation AM Antero Midstrm
由于我们希望从原始行输出、每行的ticker和company中获得多个列输出,因此我们必须使用以下技术之一:
将多列中的值连接到一列中
仅当您可以在需要使用单个值之前轻松拆分这些列,或者不需要处理这些列时才有用,这纯粹是为了可视化。
执行多个PIVOT查询并连接结果
当每列的聚合逻辑不同时,或者您不是简单地将行值转换为列值,而是将多行聚合为单个单元格响应时,这是必需的。
在像这样的场景中,当我们只是转置值,例如,聚合的结果将匹配原始单元格值,我认为这是一个小技巧,但也可能比其他方法的语法更少。
我之所以说hack是因为核心PIVOT逻辑是重复的,这使得随着查询的发展更难维护
在唯一列上执行单个透视,在其他表上联接以构建其他列
这很容易在输出中允许无限数量的额外行。PIVOT解析表的ID,该表包含我们希望在最终结果中显示的多个值。
让我们先看3,因为这演示了单个透视以及如何为每个透视结果包含多个列:
在这个示例中,我允许每个扇区最多有8个结果,需要注意的是,必须指定透视中的所有输出列,它不是动态的
您可以使用动态查询来测试所需的最大列数,并根据这些结果生成以下查询
还要注意的是,在这个解决方案中,我们不需要在PIVOT源查询中的template13_vw表上进行联接,而是在结果上进行联接,这就是为什么PIVOT返回m_ticker的原因,我假设m_ticker是键,而不是最终结果中显示的ticker
-注意:在这里使用CTE,您可以使用表变量、临时表或您需要的任何其他内容
;有滴答声
扇区INT,
股票代码CHAR4,
m_ticker CHAR4,
扇区_char10
-模板13_vw
声明@公司表
m_ticker CHAR4,
股票代码CHAR4,
公司名称:VARCHAR100
插入@tickerData扇区,股票代码
值5,'ADNT'
,5,“自动”
,5,'THRM'
,5,'ALSN'
,5,'ALV'
,12,“他”
,12,'AM'
,12,'PHX'
,12,'NBR'
,12,'AMRC'
插入@Company ticker,Company\u name
值“ADNT”,“Adient PLC”
“汽车公司”、“汽车电池公司”
“THRM”和“Gentherm公司”
“ALSN”和“Allison Transmission Holdings,Inc.”
“阿尔夫”、“奥托立夫公司”
“HES”、“Hess公司”
“上午”和“中段”
“PHX”、“Panhandle特许权公司”
,'NBR','Nabors Industries Ltd.'
“AMRC”、“Ameresco公司”
-只需重新创建一个与给定数据和查询结构匹配的记录集
更新@tickerData SET m_ticker=ticker
更新@Company SET m_ticker=ticker
-填充“扇区字符”以显示多个聚合
更新@tickerData SET sector_char='|'+castsector为varchar+'|'
-未经验证的数据证明
选择d.section、d.section\u char、d.ticker、v.company\u name、按d.section超额分配的行数、按d.section订单
来自@tickerData d,@Company v
其中,d.m_ticker=v.m_ticker
轴之前的数据如下所示:
SECTOR TICKER COMPANY
-----------------------------------------------------
5 ADNT Adient PLC
5 AUTO Autobytel Inc.
5 THRM Gentherm Inc
5 ALSN Allison Transmission Holdings, Inc.
5 ALV Autoliv, Inc.
12 HES Hess Corporation
12 AM Antero Midstrm
12 PHX Panhandle Royalty Company
12 NBR Nabors Industries Ltd.
12 AMRC Ameresco, Inc.
sector sector_char ticker company_name rn
------------------------------------------------------------------------
5 |5| ADNT Adient PLC 1
5 |5| AUTO Autobytel Inc. 2
5 |5| THRM Gentherm Inc 3
5 |5| ALSN Allison Transmission Holdings, Inc. 4
5 |5| ALV Autoliv, Inc. 5
12 |12| HES Hess Corporation 1
12 |12| AM Antero Midstrm 2
12 |12| PHX Panhandle Royalty Company 3
12 |12| NBR Nabors Industries Ltd. 4
12 |12| AMRC Ameresco, Inc. 5
现在,可视化您期望的结果子集,以显示我创建的多个列操作的限制,这些列操作将包含在最终输出中
sector sector_char ticker_1 company_1 ticker_2 company_2
-----------------------------------------------------------------------------
5 |5| ADNT Adient PLC AUTO Autobytel Inc.
12 |12| HES Hess Corporation AM Antero Midstrm
由于我们希望从原始行输出、每行的ticker和company中获得多个列输出,因此我们必须使用以下技术之一:
将多列中的值连接到一列中
仅当您可以在需要使用单个值之前轻松拆分这些列,或者不需要处理这些列时才有用,这纯粹是为了可视化。
执行多个PIVOT查询并连接结果
当每列的聚合逻辑不同时,或者您不是简单地将行值转换为列值,而是将多行聚合为单个单元格响应时,这是必需的。
在像这样的场景中,当我们只是转置值,例如,聚合的结果将匹配原始单元格值,我认为这是一个小技巧,但也可能比其他方法的语法更少。
我之所以说hack是因为核心PIVOT逻辑是重复的,这使得随着查询的发展更难维护
在唯一列上执行单个透视,在其他表上联接以构建其他列
这很容易在输出中允许无限数量的额外行。PIVOT解析表的ID,该表包含我们希望在最终结果中显示的多个值。
让我们先看3,因为这演示了单个透视以及如何为每个透视结果包含多个列:
在这个示例中,我允许每个扇区最多有8个结果,需要注意的是,必须指定透视中的所有输出列,它不是动态的
您可以使用动态查询来测试所需的最大列数,并根据这些结果生成以下查询
还要注意的是,在这个解决方案中,我们不需要在PIVOT源查询中的template13_vw表上进行联接,而是在结果上进行联接,这就是为什么PIVOT返回m_ticker的原因,我假设m_ticker是键,而不是最终结果中显示的ticker
-注意:在这里使用CTE,您可以使用表变量、临时表或您需要的任何其他内容
;以TickersBySector为例
-必须在输出中指定固定的列数
选择扇区,扇区字符[1]为[m_ticker_1],[2]为[m_ticker_2],[3]为[m_ticker_3],[4]为[m_ticker_4],[5]为[m_ticker_5],[6]为[m_ticker_6],[7]为[m_ticker_7],[8]为[m_ticker_8]
从…起
选择d.section、d.section\u char、d.m\u ticker、按d.section超额分配的行数、按d.section顺序
来自模板13_ticker_data d/*OPs语法*/
-在@tickerData d/*中,将其与验证表变量一起使用*/
数据
支点
最大自动售票机
对于[1]、[2]、[3]、[4]、[5]、[6]、[7]、[8]中的rn
作为数据透视表
-要与验证表变量一起使用,请将“template13_vw”替换为“@Company”
选择扇区,扇区\字符
,c1.【股票代码】为【股票代码1】,c1.公司名称为【公司代码1】
,c2.[股票代码]为[股票代码2],c2.公司名称为[公司代码2]
,c3.【股票代码】为【股票代码3】,c3.公司名称为【公司代码3】
,c4.【股票代码】为【股票代码4】,c4.公司名称为【公司代码4】
,c5.【股票代码】为【股票代码5】,c5.公司名称为【公司代码5】
,c6。[股票代码]为[ticker_6],c6.公司名称为[company_6]
,c7.[ticker]as[ticker_7],c7.公司名称as[company_7]
,c8.[ticker]as[ticker_8],c8.company_name as[company_8]
来自TickersBySector
c1.m\U ticker上的左侧外部联接模板13\U vw c1=TickerBySector.m\U ticker\U 1
c2.m_ticker上的左外连接模板13_vw c2=TickerBySector.m_ticker_2
c3.m_报价器上的左外连接模板13_vw c3