2014-01-23 33 views
0

在表table鑑於這些條目:什麼是簡單的方法來執行這個複雜的SELECT查詢?

user entry 

A  1 
A  2 
A  5 
A  6 
B  1 
B  2 
B  3 
B  4 
B  5 
B  6 
C  1 
C  4 
D  1 
D  2 
D  5 
D  6 
D  7 
D  9 

我們有一個子集entries_A一起工作,這是數組[1,2,5,6]

問題:

  1. 查找具有相同的條目[1,2,5,6]多,例如所有用戶[1,2,5,6,7]或[1,2,3,5,6]。
  2. 查找所有擁有大量相同條目(以及更多)的用戶,例如[1,2,5,9]或[2,5,6,3]。

第一個問題的最佳解決方案,我可以想出,是以下選擇查詢:

SELECT DISTINCT user AS u FROM table WHERE EXISTS (SELECT * FROM table WHERE entry=1 AND user=u) 
            AND EXISTS(SELECT * FROM table WHERE entry=2 AND user=u) 
            AND EXISTS(SELECT * FROM table WHERE entry=5 AND user=u) 
            AND EXISTS(SELECT * FROM table WHERE entry=6 AND user=u) 

在另一方面,我得到一個感覺,有一些代數矢量問題潛伏以下表面(特別是對於問題二),但我似乎無法把頭圍住它。

歡迎任何想法!

回答

2

我認爲最簡單的方法來執行這種類型的查詢是使用聚合和having。這是一個例子。

要獲得正好具有這四個要素A的:

select user 
from table 
group by user 
having sum(entry in (1,2,5,6)) > 0 and 
     count(distinct entry) = 4; 

要得到的是有這四個要素,也許別人:

select user 
from table 
group by user 
having sum(entry in (1,2,5,6)) > 0 and 
     count(distinct entry) >= 4; 

要由他們匹配的數量訂購用戶和其他匹配的數量:

select count(distinct case when entry in (1, 2, 5, 6) then entry end) as Matches, 
     count(distinct case when entry not in (1, 2, 5, 6) then entry end) as Others, 
     user 
from table 
group by user 
order by Matches desc, Others; 
+0

感謝您的最後一個查詢。我沒有要求,但我需要的東西幾乎完全一樣。 – Honoki

+0

不知道你從哪裏得到的,但是在(1,2,5,6)中有條目根本不起作用,因爲只有聚合函數在having子句中起作用。 – fancyPants

+0

@fancyPants。 。 。謝謝。固定。 –

1

對於第一個問題:

SELECT user FROM (
    SELECT 
    DISTINCT user 
    FROM 
    table 
    WHERE entry IN (1,2,5,6) 
) a JOIN table b ON a.user = b.user 
GROUP BY a.user 
HAVING COUNT(*) >= 4 

對於第二個問題只是降低having子句中的計數。

+0

這貌似簡單,我正在尋找優雅的解決方案。當我確定它是100%正確的時候,我會接受它。 – Honoki

+1

請注意,只有組合用戶條目是唯一的,這纔會起作用。否則,此查詢還會返回具有例如4個值爲1的條目的用戶。@ – hage

+0

@hage,是的,我意識到這一點。我假設這就是爲什麼fancyPants編輯他的答案。 – Honoki

1

這是我如何對你的第一個查詢(儘管我認爲戈登·利諾夫的回答是更有效):

select distinct user from so s1 
where not exists ( 
    select * from so s2 where s2.entry in (1,2,5,6) 
     and not exists ( 
      select * from so s3 where s2.entry = s3.entry and s1.user = s3.user 
    ) 
); 

對於第二個問題,你需要指定什麼a lot應該是說......三,四......

+0

不... ...'s1'在第一行被定義,並且它對內部查詢是已知的。內部查詢不會在執行前執行。但是,對於最外層查詢(s1)中的每一行,內部塊將被執行。 – hage

相關問題