计算PostgreSQL表中每个值出现的次数?

时间:2014-10-17 18:22:29

标签: sql postgresql pivot

所以我有一个包含三个重要列的表:商店位置,客户和购买数量。类似的东西:

Store   |   Customer   |   Number of purchases
A           Larry          2
B           Moe            4
C           Curly          7
B           Tina           1
A           Dina           6
C           Archer         12
D           Mallory        3

我想做的是计算每次购买次数。也就是说,计算客户进行1次购买,2次购买,3次购买,4次购买等的次数,类似于直方图,按商店分组。

Store   |   1 Purchase   |   2 Purchases   |   3 Purchases...
A           1                3                 2
B           2                1                 4
C           1                6                 8
D           4                4                 2 

有没有聪明的方法可以做到这一点,而无需手动找出最大购买数量,并创建一个分支计数来计算每一个?所以我已经

SELECT Store,
      Count(CASE number_of_purchases when 1 then 1 else null end) as 1_purchase,
      Count(CASE number_of_purchases when 2 then 1 else null end) as 2_purchase,
      Count(CASE number_of_purchases when 3 then 1 else null end) as 3_purchase...
FROM table
GROUP BY Store;

但是,由于最大数量可以随时间变化,我希望查询自动计算并考虑到这一点。任何帮助将不胜感激!

2 个答案:

答案 0 :(得分:1)

要获得正确的数据,您只需要group by和聚合函数。

select store, number_of_purchases, count(number_of_purchases)
from Table1
group by store, number_of_purchases
order by store, number_of_purchases;

对于格式,您需要使用tablefunc扩展中的一个crosstab()函数。这些方面的东西。

select * 
from crosstab('select store, number_of_purchases, count(number_of_purchases)
               from Table1
               group by store, number_of_purchases
               order by 1, 2', 
              'select n from generate_series(1, 12) n order by 1') 
     as (store text, "1" int,  "2" int,  "3" int,  "4" int, 
                     "5" int,  "6" int,  "7" int,  "8" int, 
                     "9" int, "10" int, "11" int, "12" int)
;

就个人而言,我不喜欢这种数据的交叉表。你最终可能得到数百或数千列宽的输出,大多数"单元"空。

答案 1 :(得分:0)

试试这个:

SELECT
    Store, number_of_purchases, COUNT(DISTINCT number_of_purchases) AS cnt
FROM table
GROUP BY Store, number_of_purchases

结果将按行排列(不在列中),因为您不知道每个商店的最大购买次数。

对结果进行循环很容易,因为它们将按Store和number_of_purchases排序。