2014-03-27 19 views
2

我有一個查詢,我可以運行,產生這種行:如何爲每個Y找到最相關的X?

ID | category | property_A | property_B 
----+----------+------------+------------ 
    1 |  X |  tall |  old 
    2 |  X |  short |  old 
    3 |  X |  tall |  old 
    4 |  X |  short |  young 
    5 |  Y |  short |  old 
    6 |  Y |  short |  old 
    7 |  Y |  tall |  old 

我想找到,每個categoryproperty_B,什麼是最常見的property_A,並將它放入另一臺某處供以後使用。所以在這裏我想知道,在X類中,老年人往往身材矮小,年輕人矮,而在Y類中,老年人往往很矮。

每列的域是有限的,並不是太大 - 有200個類別的東西,還有一兩個property_A和property_B。所以我可以在我的客戶端上編寫一個愚蠢的腳本,查詢數據庫200 * 12 * 12次執行有限的查詢,但是這似乎是一定是錯誤的方法,以及浪費,因爲生成此表和然後扔掉它的大部分。

但我甚至不知道要查找哪個單詞以找到正確的方法:「sql查找相關行」顯示如何查找整數相關性,但我對整數不感興趣。那麼我該怎麼做呢?

回答

2

我建議的GROUP BYDISTINCT ON組合,這是更快/ Postgres裏簡單/更優雅:

SELECT DISTINCT ON (category, property_b) 
     category, property_b, property_a, count(*) AS ct 
FROM tbl 
GROUP BY category, property_b, property_a 
ORDER BY category, property_b, ct DESC; 

返回:

category | property_b | property_a | ct 
---------+------------+------------+---- 
X  | old  | tall  | 2 
X  | young  | short  | 1 
Y  | old  | short  | 2 

如果多個對等並列爲最常用的值,只有一個任意選擇被返回。

由於在步驟DISTINCT之前應用了聚合(GROUP BY),所以此工作在沒有子查詢的單個查詢級別中。爲DISTINCT ON詳細說明:
Select first row in each GROUP BY group?

SQL Fiddle.

3

您可以通過聚合和窗口/分析函數輕鬆完成此操作。你想要排名靠前的一個。下面回到最流行答:

select category, property_b, property_a as MostPopularA 
from (select category, property_b, property_a, count(*) as cnt, 
      row_number() over (partition by category, property_b order by count(*) desc) as seqnum 
     from table t 
     group by category, property_b, property_a 
    ) t 
where seqnum = 1; 

如果你想獲得的所有值時,有一條領帶,然後用dense_rank()代替row_number()

相關問題