2014-01-23 32 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

相关问题