我在Stack Overflow和网页上搜索了一个我需要做的例子,似乎无法弄清楚如何应用旋转来完成我需要做的事情。也许使用Pivot根本就不是正确的答案,但似乎我缺乏理解可能会妨碍。我有一个表格,其数据如下所示:
year property type market total taxable total parcel count
---- ------------- ------------ ------------- ------------
2012 Real 23453 34563 123
2012 Personal 53434 65432 321
2013 Real 24565 23546 345
2013 Personal 64453 45636 342
2014 Real 76586 78645 876
2014 Personal 56775 67556 897
我需要把它变成一个结果,将所有值显示为每年一行,如下所示:
year real market real taxable real count pers market pers taxable pers count
---- ----------- ------------ ---------- ----------- ------------ ----------
2012 23453 34563 123 53434 65432 321
2013 24565 23546 345 64453 45636 342
2014 76586 78645 876 56775 67556 897
我看到的所有数据透视表示例都将列名称显示为源数据中列的实际值,这对我来说似乎并非如此。而我无法动态构建SQL。顺便说一下,“属性类型”值是一个已知的集合,所以我确切知道输出所需的列数。
以简单的方式在SQL中执行此操作吗?它似乎应该是......
答案 0 :(得分:1)
我不确定您使用的DBMS,但我相信我的查询应该适合您(我使用的是SQL Server)。
DECLARE @yourTable TABLE ([year] INT,[Property Type] VARCHAR(20),[Market Total] INT,[Taxable Total] INT,[Parcel Count] INT);
INSERT INTO @yourTable
VALUES (2012,'Real',23453,34563,123),
(2012,'Personal',53434,65432,321),
(2013,'Real',24565,23546,345),
(2013,'Personal',64453,45636,342),
(2014,'Real',76586,78645,876),
(2014,'Personal',56775,67556,897);
SELECT [year],
MAX(CASE WHEN [Property Type] = 'Real' THEN [Market Total] END) AS [Real Market],
MAX(CASE WHEN [Property Type] = 'Real' THEN [Taxable Total] END) AS [Real Taxable],
MAX(CASE WHEN [Property Type] = 'Real' THEN [Parcel Count] END) AS [Real Count],
MAX(CASE WHEN [Property Type] = 'Personal' THEN [Market Total] END) AS [Personal Market],
MAX(CASE WHEN [Property Type] = 'Personal' THEN [Taxable Total] END) AS [Personal Taxable],
MAX(CASE WHEN [Property Type] = 'Personal' THEN [Parcel Count] END) AS [Personal Count]
FROM @yourTable
GROUP BY [year]
答案 1 :(得分:0)
您可以使用INNER JOIN查询来实现结果:
这是MySQL语法:
SELECT t1x.`year`, `real market`, `real taxable`, `real count`,
`pers market`, `pers taxable`, `pers count`
FROM (SELECT `year`, `market total` AS `real market`,
`taxable total` AS `real taxable`, `parcel count` AS `real count`
FROM t1
WHERE `property type` = 'Real') t1x
INNER JOIN (SELECT `year`, `market total` AS `pers market`,
`taxable total` AS `pers taxable`, `parcel count` AS `pers count`
FROM t1
WHERE `property type` = 'Personal') t1y
ON t1x.`year` = t1y.`year`
以下是SQL Fiddle,因此您可以了解它是如何运作的。
基本上,您可以从表中选择值(我称之为 t1 )为两个临时表 t1x 和 t1y 。在 t1x 表格中,您可以选择 t1 行,其中属性类型列值真实并进入 t1y < / strong>该值个人。并且在年列中加入两个表...
SQL Server语法几乎相同,唯一的区别在于它们如何处理MySQL中的两个单词列我们使用后引用(`)而在SQL Server中我们使用这样的括号[];
这里的语法如下:
SELECT t1x.[year], [real market], [real taxable], [real count],
[pers market], [pers taxable], [pers count]
FROM (SELECT [year], [market total] AS [real market],
[taxable total] AS [real taxable], [parcel count] AS [real count]
FROM t3
WHERE [property type] = 'Real')AS t1x
INNER JOIN (SELECT [year], [market total] AS [pers market],
[taxable total] AS [pers taxable], [parcel count] AS [pers count]
FROM t1
WHERE [property type] = 'Personal') t1y
ON t1x.[year] = t1y.[year]
如果你使用任何其他数据库,至少你知道如何处理这个问题......
GL!
答案 2 :(得分:0)
我需要报告的数据经常出现相同类型的问题,我使用了这两个选项并查看了性能问题,以帮助我选择在给定报告中使用的选项。通常我会将最小的结果数据推送到临时表,然后进行最终的操作以进行报告。这样可以减少I / O负载。
IF OBJECT_ID('tempdb..#SAMPLEDATA') IS NOT NULL DROP TABLE #SAMPLEDATA;
CREATE TABLE #SAMPLEDATA
(
[Year] INT,
[Property Type] VARCHAR(50),
[Market] DECIMAL(18,2),
[Taxable] DECIMAL(18,2),
[Parcel] INT
)
INSERT INTO #SAMPLEDATA([Year],[Property Type],[Market],[Taxable],[Parcel]) VALUES
(2012,'Real',23453,34563,123),
(2012,'Personal',53434,65432,321),
(2013,'Real',24565,23546,345),
(2013,'Personal',64453,45636,342),
(2014,'Real',76586,78645,876),
(2014,'Personal',56775,67556,897)
-- OPTION 1 (LINKING MULTIPLE PIVIOTS) -- DOWNSIDE -- HITTING THE DATA NUMBEROUS TIMES HIGH I/O
SELECT
L.[Year],
D1.[real market],
D2.[real taxable],
D3.[real count],
D1.[pers market],
D2.[pers taxable],
D3.[pers count]
FROM
(SELECT [YEAR] FROM #SAMPLEDATA GROUP BY [YEAR]) AS L
LEFT OUTER JOIN (SELECT [Year],[Real] AS [real market],[Personal] AS [pers market] FROM (SELECT [Year],[Property Type],[Market] FROM #SAMPLEDATA) AS P1 PIVOT (SUM([Market]) FOR [Property Type] IN ([Real],[Personal])) AS DATA1) AS D1
ON L.[Year] = D1.[Year]
LEFT OUTER JOIN (SELECT [Year],[Real] AS [real taxable],[Personal] AS [pers taxable] FROM (SELECT [Year],[Property Type],[Taxable] FROM #SAMPLEDATA) AS P2 PIVOT (SUM([Taxable]) FOR [Property Type] IN ([Real],[Personal])) AS DATA2) AS D2
ON L.[Year] = D2.[Year]
LEFT OUTER JOIN (SELECT [Year],[Real] AS [real count],[Personal] AS [pers count] FROM (SELECT [Year],[Property Type],[Parcel] FROM #SAMPLEDATA) AS P3 PIVOT (SUM([Parcel]) FOR [Property Type] IN ([Real],[Personal])) AS DATA3) AS D3
ON L.[Year] = D3.[Year]
-- OPTION 2 (CASE SUMS)
SELECT
[Year],
SUM (CASE WHEN [Property Type] = 'Real' THEN [Market] ELSE 0 END) AS [real market],
SUM (CASE WHEN [Property Type] = 'Real' THEN [Taxable] ELSE 0 END) AS [real taxable],
SUM (CASE WHEN [Property Type] = 'Real' THEN [Parcel] ELSE 0 END) AS [real count],
SUM (CASE WHEN [Property Type] = 'Personal' THEN [Market] ELSE 0 END) AS [pers market],
SUM (CASE WHEN [Property Type] = 'Personal' THEN [Taxable] ELSE 0 END) AS [pers taxable],
SUM (CASE WHEN [Property Type] = 'Personal' THEN [Parcel] ELSE 0 END) AS [pers count]
FROM
#SAMPLEDATA
GROUP BY
[Year]
答案 3 :(得分:0)
经过大量的反复试验并查看其他示例后,我终于想出了一种使用PIVOT操作的方法。我想使用数据透视而不是上述解决方案的原因是因为我必须查询的真实数据超过20&#34;属性类型&#34;每个&#34;属性类型&#34;有4个值,这使得解决问题成为一个怪物,但......这是我能够提出的枢纽解决方案:
with sample_data([year], [property_type], [market_total], [taxable_total], [parcel_count])
as
(
select 2012, 'Real', 23453, 34563, 123
union select 2012, 'Personal', 53434, 65432, 321
union select 2013, 'Real', 24565, 23546, 345
union select 2013, 'Personal', 64453, 45636, 342
union select 2014, 'Real', 76586, 78645, 876
union select 2014, 'Personal', 56775, 67556, 897
),
categorized_data ([year], [column_name], [column_value])
as
(
select [year], [property_type] + '_market_total', [market_total] from sample_data
union select [year], [property_type] + '_taxable_total', [taxable_total] from sample_data
union select [year], [property_type] + '_parcel_count', [parcel_count] from sample_data
)
select * from categorized_data
pivot
(
max(column_value) for column_name in
(
[Real_market_total],
[Real_taxable_total],
[Real_parcel_count],
[Personal_market_total],
[Personal_taxable_total],
[Personal_parcel_count]
)
) as pvt
希望这会帮助那些一开始就像我一样难过的人。