我们需要采用多行多列并将其转换为每个键1行。我有一个数据透视查询,但是不起作用。我收到一些有关“列定义不明确”的错误
我们的数据如下:
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.
我们需要的是每个ID 1行,每个TICKER / COMPANY在不同的列中。因此,输出如下所示:
5 ADNT Adient PLC AUTO Autobytel Inc. THRM Gentherm Inc........
您明白了。每个ID 1行,彼此对应的值在其自己的列中。我尝试过的查询是:
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;
答案 0 :(得分:0)
首先要了解数据透视,您需要在结果集中选择一个列作为PIVOT
锚点,数据将围绕数据透视旋转,这在{{1 }}子句。
您只能
FOR
PIVOT
的一列,但是您可以在子查询中或根据联接或视图构造此列,作为您的目标数据查询, OPFOR
,但您可以使用任何希望的SQL机制,甚至可以使用ROW_NUMBER()
语句来构建自定义列,以便在数据集中没有自然列要使用时进行旋转。
CASE
将为PIVOT
列中的每个 value 列创建一列,并为该列提供您所使用的聚合函数的值指定
它有助于可视化构造的记录集,在应用数据透视表之前,以下SQL可以重新创建OP呈现的数据方案。我在这里使用表变量来代替OP表和视图。
FOR
数据透视表之前的数据如下:
-- template13_ticker_data (with sector_char added)
DECLARE @tickerData Table
(
sector INT,
ticker CHAR(4),
m_ticker CHAR(4),
sector_char char(10)
)
-- template13_vw
DECLARE @Company Table
(
m_ticker CHAR(4),
ticker CHAR(4),
company_name VARCHAR(100)
)
INSERT INTO @tickerData (sector, ticker)
VALUES (5 ,'ADNT')
,(5 ,'AUTO')
,(5 ,'THRM')
,(5 ,'ALSN')
,(5 ,'ALV')
,(12,'HES')
,(12,'AM')
,(12,'PHX')
,(12,'NBR')
,(12,'AMRC')
INSERT INTO @Company (ticker, company_name)
VALUES ('ADNT','Adient PLC')
,('AUTO','Autobytel Inc.')
,('THRM','Gentherm Inc')
,('ALSN','Allison Transmission Holdings, Inc.')
,('ALV ','Autoliv, Inc.')
,('HES ','Hess Corporation')
,('AM ','Antero Midstrm')
,('PHX ','Panhandle Royalty Company')
,('NBR ','Nabors Industries Ltd.')
,('AMRC','Ameresco, Inc.')
-- Just re-creating a record set that matches the given data and query structure
UPDATE @tickerData SET m_ticker = ticker
UPDATE @Company SET m_ticker = ticker
-- populate 'sector_char' to show multiple aggregates
UPDATE @tickerData SET sector_char = '|' + cast(sector as varchar) + '|'
-- Unpivoted data Proof
SELECT d.sector, d.sector_char, d.ticker, v.company_name, ROW_NUMBER() OVER(PARTITION BY d.sector ORDER BY d.sector) rn
FROM @tickerData d, @Company v
WHERE d.m_ticker = v.m_ticker
现在可视化您期望的结果子集,以显示我创建的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_char
因为我们要从原始行输出中获得多于一列的输出(每行中的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
查询并加入结果
我说 hack 是因为核心PIVOT逻辑是重复的,这使得查询的发展变得更加困难。
PIVOT
,在其他表上联接以构建其他列
PIVOT
解析包含要在最终结果中显示的多个值的表的ID。让我们首先看3,因为这演示了一个PIVOT,以及如何为每个PIVOT结果包括多列:
在此示例中,每个扇区最多允许8个结果,请务必注意,您必须指定
PIVOT
中的所有输出列,它不是动态的。您可以使用动态查询来测试所需的最大列数,并根据这些结果生成以下查询。
还要注意,在此解决方案中,我们不需要在PIVOT
源查询中的template13_vw
表上进行联接,而是对结果进行了联接,这就是枢轴返回{ {1}}(我认为是关键),而不是最终结果中显示的PIVOT
。
m_ticker
以下是同一查询,使用多个ticker
查询将它们连接在一起。
请注意,在这种情况下,两个-- NOTE: using CTE here, you could use table variables, temporary tables or whatever else you need
;WITH TickersBySector as
(
-- You must specify the fixed number of columns in the output
SELECT sector, sector_char, [1] as [m_ticker_1],[2] as [m_ticker_2],[3] as [m_ticker_3],[4] as [m_ticker_4],[5] as [m_ticker_5],[6] as [m_ticker_6],[7] as [m_ticker_7],[8] as [m_ticker_8]
FROM (
SELECT d.sector, d.sector_char, d.m_ticker, ROW_NUMBER() OVER(PARTITION BY d.sector ORDER BY d.sector) rn
FROM template13_ticker_data d /* OPs Syntax */
-- FROM @tickerData d /* Use this with the proof table variables */
) data
PIVOT (
MAX(m_ticker)
FOR rn IN ( [1],[2],[3],[4],[5],[6],[7],[8])
) as PivotTable
)
-- To use with the proof table variables, replace 'template13_vw' with '@Company'
SELECT sector, sector_char
,c1.[ticker] as [ticker_1], c1.company_name as [company_1]
,c2.[ticker] as [ticker_2], c2.company_name as [company_2]
,c3.[ticker] as [ticker_3], c3.company_name as [company_3]
,c4.[ticker] as [ticker_4], c4.company_name as [company_4]
,c5.[ticker] as [ticker_5], c5.company_name as [company_5]
,c6.[ticker] as [ticker_6], c6.company_name as [company_6]
,c7.[ticker] as [ticker_7], c7.company_name as [company_7]
,c8.[ticker] as [ticker_8], c8.company_name as [company_8]
FROM TickersBySector
LEFT OUTER JOIN template13_vw c1 ON c1.m_ticker = TickersBySector.m_ticker_1
LEFT OUTER JOIN template13_vw c2 ON c2.m_ticker = TickersBySector.m_ticker_2
LEFT OUTER JOIN template13_vw c3 ON c3.m_ticker = TickersBySector.m_ticker_3
LEFT OUTER JOIN template13_vw c4 ON c4.m_ticker = TickersBySector.m_ticker_4
LEFT OUTER JOIN template13_vw c5 ON c5.m_ticker = TickersBySector.m_ticker_5
LEFT OUTER JOIN template13_vw c6 ON c6.m_ticker = TickersBySector.m_ticker_6
LEFT OUTER JOIN template13_vw c7 ON c7.m_ticker = TickersBySector.m_ticker_7
LEFT OUTER JOIN template13_vw c8 ON c8.m_ticker = TickersBySector.m_ticker_8
都带回附加的公共列PIVOT
并不重要,因此当汇总或附加的公共列可能因不同的结果而不同时,请使用这种语法样式设置。
PIVOT