带count的简单sql查询

时间:2012-10-25 00:26:43

标签: sql sqlite count nested

我正在使用SQLite。 我需要一个简单问题的帮助。 这是我的三张桌子:

--------------
problem
--------------
id (primary key)
question_id (foreign key)

--------------
question
--------------
id (primary key)
answer_id (foreign key)

--------------
answer
--------------
id (primary key)

我想在问题的每个问题中得到至少有N个答案的所有问题。我给你举个例子:

-------
problem
id 
1
2


-------
question 
id   problem_id
1    1
2    1
3    1
4    2

-------
answer
id   question_id
1    1
2    1
3    1
4    2
5    2
6    3
7    4
8    4

如果n = 2,我的结果应该是problem_id = 2.

我试过这个:

   select distinct question.problem_id 
   from answer, question
   where answer.question_id = question.id
   group by answer.question_id
   having count(*) >= 2

但它不起作用,因为至少有一个问题至少有2个答案会出现问题。所有问题都必须满足这一条件。

有什么问题吗?

3 个答案:

答案 0 :(得分:3)

select problem_id
from
(
    select q.problem_id, q.id, count(a.id) answercount
    from question q
    left join answer a on a.question_id = q.id
    group by q.problem_id, q.id
) g
group by problem_id
having min(answercount) >= 2

替代方案(例如4个答案)

select distinct q.problem_id
from question q
left join answer a on a.question_id = q.id
left join answer b on b.question_id = q.id and a.id < b.id
left join answer c on c.question_id = q.id and b.id < c.id
left join answer d on d.question_id = q.id and c.id < d.id
where d.id is not null

您可以根据需要扩展此模式。如果你真的需要一个参数化的单个查询,你可以做一些疯狂的事情,如连接6次,改变WHERE子句,如下所示:

where case when f.id is not null then 6
           when e.id is not null then 5
           when d.id is not null then 4
           when c.id is not null then 3
           when b.id is not null then 2
           else 1 end >= {{YourParamHere}}

答案 1 :(得分:2)

以下是我在T-SQL中的问题:

declare @problem table(id bigint not null primary key clustered)
declare @question table(id bigint not null primary key clustered, problem_id bigint)
declare @answer table(id bigint not null primary key clustered, question_id bigint)

declare @n int = 2

insert @problem
      select 1 
union select 2

insert @question
      select 1, 1 
union select 2, 1
union select 3, 1
union select 4, 2

insert @answer 
      select 1, 1 
union select 2, 1
union select 3, 1
union select 4, 2
union select 5, 2
union select 6, 3
union select 7, 4
union select 8, 4

select p.id --, p.name, p.description, p.etc
from @problem p
where @n >= ALL --http://msdn.microsoft.com/en-us/library/ms178543.aspx
(
    select COUNT(a.id) 
    from @question q
    left outer join @answer a
        on q.id = a.question_id
    where p.id = q.problem_id
    group by q.id
)

注意:表格架构与问题略有不同,因为问题中的架构与示例数据不匹配。

ALTERNATIVE

(基于@ RichardTheKiwi的答案,内部SQL移动到临时表)

declare @tempTable table (pid bigint, qid bigint, aidCount bigint)

insert @tempTable
select q.problem_id, q.id, count(a.id) answercount
from @question q
left join @answer a on a.question_id = q.id
group by q.problem_id, q.id

select pid
from @tempTable
group by pid 
having min(aidCount) >= @n 

答案 2 :(得分:1)

重写为相关子查询。我们不是在每个问题中找到至少N个答案的问题,而是找到问题,其中没有问题的答案少于N个答案:

SELECT id AS problem_id
FROM problem AS p 
WHERE NOT EXISTS
      ( SELECT 1
        FROM question AS q
          LEFT JOIN answer AS a 
            ON a.question_id = q.id
        WHERE q.problem_id = p.id
        GROUP BY q.id
        HAVING COUNT(a.question_id) < 2
      ) ;