在没有Pivot函数的SQL中创建数据透视表

时间:2014-09-19 16:58:21

标签: sql postgresql pivot psql

所有

我有下表。

SalesDate   SubChannel      Country  NetQuantity
20140826    TV Attributable      CA          194
20140826    Unknown              CA           60
20140826    Web Property         CA           64
20140826    Overall              CA          264
20140826    Search               CA           70

我想将此信息显示为数据透视表。

在我使用以下代码来实现这一目标之前,我必须迁移到当前系统,不支持数据透视功能。

Select      SalesDate,
    Country,
    [Search],
    [Unknown],
    [Web Property],
    [TV Attributable],
    [Overall]
From temp
PIVOT
(
Sum([NetQuantity])
FOR [SubChannel] IN ([Search],[Unknown],[Web Property],[TV Attributable],[Overall])
) as p

有人可以帮助我完成以下输出:

SalesDate   Country Search  Unknown  WebProperty       TVAttributable      Overall
20140826         CA     70       60           64                  194          264

2 个答案:

答案 0 :(得分:0)

您可以使用CASE语句与GROUP BY一起“手动”执行数据透视;

SELECT "SalesDate", MAX("Country") "Country",
  MAX(CASE WHEN "SubChannel"='Search' 
           THEN "NetQuantity" END) "Search",
  MAX(CASE WHEN "SubChannel"='Unknown' 
           THEN "NetQuantity" END) "Unknown",
  MAX(CASE WHEN "SubChannel"='Web Property' 
           THEN "NetQuantity" END) "WebProperty",
  MAX(CASE WHEN "SubChannel"='TV Attributable' 
           THEN "NetQuantity" END) "TVAttributable",
  MAX(CASE WHEN "SubChannel"='Overall' 
           THEN "NetQuantity" END) "Overall"
FROM temp
GROUP BY "SalesDate";

An SQLfiddle to test with

基本上,CASE语句在子通道匹配时选择一个值,如果不匹配则选择null。然后使用MAX为每个子信道选择最大(非空)匹配。

如果需要按国家/地区拆分销售日期,则只需将MAX("Country")表达式替换为“国家/地区”,然后将国家/地区添加到GROUP BY

答案 1 :(得分:0)

您可以使用CASE来确定每个类别的总结。当你在示例数据透视表中使用SUM时,我想你可能想要这个而不是MAX:

Select
    "SalesDate",
    "Country",
    sum(case when "SubChannel" = 'Search' then "NetQuantity" else 0 end) "Search",
    sum(case when "SubChannel" = 'Unknown' then "NetQuantity" else 0 end) "Unknown",
    sum(case when "SubChannel" = 'Web Property' then "NetQuantity" else 0 end) "Web Property",
    sum(case when "SubChannel" = 'TV Attributable' then "NetQuantity" else 0 end) "TV Attributable",
    sum(case when "SubChannel" = 'Overall' then "NetQuantity" else 0 end) "Overall"
from temp
group by "SalesDate", "Country"

Sample SQL Fiddle