2016-04-26 4 views
2

私は、次の表があります。MODEアグリゲーション機能

顧客

customer_id name 
---------------- 
1   bob 
2   alice 
3   tim 

購入

id customer_id item_bought 
-------------------------- 
1 1   hat 
2 1   shoes 
3 2   glasses 
3 2   glasses 
4 2   book 
5 3   shoes 
6 1   hat 

をそして、私は次のような結果にしたい:

customer_name item_bought_most_often 
------------------------------------ 
bob   hat 
alice   glasses 
tim   shoes 

私はこの(実際に試したことのない、単なるアイデア)のようにこれを行うだろう:

SELECT customer.name as customer_name, 
    MODE(item_bought), as item_bought_most_ofen 
FROM customers 
INNER JOIN purchases USING (customer_id) 
GROUP_BY customer_id 

しかし、MODE aggregation functionは赤方偏移に存在しません。

Redshift user defined functionsは、集計関数ではなく、通常のスカラ関数であるようです。だから私は自分でそれを定義できるとは思わない。

回避策はありますか?

答えて

2

あなたはrow_number()を使用してmode()を模倣することができます。

select name, item_bought 
from (select c.name, p.item_bought, count(*) as cnt, 
      row_number() over (order by count(*) desc) as seqnum 
     from customers c join 
      purchases p 
      using (customer_id) 
     group by c.name, p.item_bought 
    ) cp 
where seqnum = 1; 
+0

Amazon Redshiftは、同じレベルで、「cnt」**: 'select count(*)をcnt、 row_number()を(cnt descの順)seqnumとして参照できますか? – lad2025

+0

@ lad2025。 。 。 Arrrgh。最近、Google BigQueryが多すぎます。 –

1

あなたが最初COUNT一人一人の購入し、その後RANK()ウィンドウ機能を使用できます。

SELECT name AS customer_name, item_bought AS item_bought_most_often 
FROM(SELECT name,item_bought,RANK() OVER(PARTITION BY name ORDER BY cnt DESC) rnk 
    FROM (SELECT c.name, p.item_bought, COUNT(*) AS cnt 
      FROM customers c 
      JOIN purchases p 
      ON p.customer_id = c.customer_id 
      GROUP BY c.name, p.item_bought) AS s1) AS s2 
WHERE rnk = 1; 

LiveDemo

出力:

╔═══════════════╦════════════════════════╗ 
║ customer_name ║ item_bought_most_often ║ 
╠═══════════════╬════════════════════════╣ 
║ alice   ║ glasses    ║ 
║ bob   ║ hat     ║ 
║ tim   ║ shoes     ║ 
║ zoe   ║ pencil     ║ 
║ zoe   ║ book     ║ 
╚═══════════════╩════════════════════════╝ 

注:

RANKは、複数の最も一般的な値を処理します。

+0

私は似たようなことをしていました。私は本当に 'FIRST(my_column)、MODE(my_column)'、またはそれを定義する能力のような集約関数を期待していました。しかし、それは存在しません。別の可能性は 'SPLIT_PART(LISTAGG(id、 '、')、 '、'、1)'のようなものです。または 'udf_mode(LISTAGG、id、 '、')'とします。 udf_modeは、カンマで区切られた値の文字列に基づいてモードを計算するユーザー定義関数です。しかし、それらはすべてハッキーです。 –

+1

@pinouchon [doc](http://docs.aws.amazon.com/redshift/latest/dg/user- defined-functions.html)* 'カスタムのユーザー定義の>>スカラー<<を作成できます関数(UDF) '*。私はPostgreSQL [CREATE AGGREGATE](http://www.postgresql.org/docs/current/static/sql-createaggregate.html)のようなユーザー定義の集約関数のドキュメントは表示されません。「LISTAGG」を使用し、udf_mode働くことができます。 – lad2025