2011-03-01 41 views
0

我有一个人表唯一的ID“身份证”的人的现有名单上。这些人进行的活动都存储在一个people_activity表,与字段的类型“(活动类型,整数)和“ID”,该人物一致。我有一个查询,我拉回来许多人在一段时间,但我想添加到查询的条件,一个人或不具有执行0或多个活动。寻找不同类型的0-n行

如果我是查询一个人,这将是一个简单的“where people_activity.type = 4和people_activity.type <> 12”等,但因为我拉回了很多人,我不是相当确定如何去做。

我当前的查询,用恶劣其中对于类型子句(道歉,我简化它在我的解释):

select first , middle , last , y.dob , rid.rid as rid , rid.record_number 
      from (select first, middle, last, email, added, phone, a.revision as revision, type, lastupdated, a.rid as rid from people a inner join (select people.rid, max(revision) as revision from people group by people.rid) b on a.rid = b.rid and a.revision = b.revision) p inner join youth y on p.rid = y.rid 
        inner join language l on y.language_t = l.language_id 
        inner join cases on y.case_id = cases.id 
        inner join race r on y.race_t = r.race_id 
        inner join providers_r cp on y.provider_id = cp.provider_id 
        inner join rid on y.rid = rid.rid 
      where p.first like "c%" and p.middle like "%" and p.last like "%" and exists (select * from youth_activity where type = 2) 
      group by y.rid 
      order by last asc 

你会看到我现在做的方式,“在那里存在(选择*从youth_activity其中type = 4)”是没有好,因为简单地检查单个类型的4都存在,并不一定是具体的人在查询返回。

回答

1

MySQL的我的方法有一些性能问题存在,但在语法上,你会相关的已经有一个主查询子查询。但是如果你想has completed activities 1,2,3, not 4 and 8,然后

  where p.first like "c%" and p.middle like "%" and p.last like "%" 
      and (select count(distinct a.type) from youth_activity a where a.type in (1,2,3) and a.youthid = y.rid) = 3 
      and not exists (select * from youth_activity a where a.type in (4,8) and a.youthid = y.rid) 
+0

不会在查询中只有一个人工作a.youthid = 3子查询位结果?查询当前拉回来人的大名单。 – Christopher 2011-03-02 00:23:41

+0

号的相关性'和a.youthid = y.rid'是什么子查询(计数)的青年从主查询链接,每个数(每主查询行)对3比满足病情'已完成活动1,2,3' – RichardTheKiwi 2011-03-02 00:29:21

+0

优秀!这确实工作。spintheblack的反应是非常有益的,以及只可惜我不能使用全外连接。 – Christopher 2011-03-02 00:40:42

1

我不是从查询完全清楚,但它听起来像你想如果你想包括没有活动的人做这样的事情

SELECT COUNT(*),p.* FROM Person p 
    LEFT OUTER JOIN Person_Activity pa ON p.id = pa.id 
    WHERE (whatever your condition) 
    GROUP BY p.id 
    HAVING COUNT(*)> (number of activities) 

,你必须手动检查是否pa.id是NULL。

这里的基础上,评论

-- Get the list of all activities of interest (call this QUERY X). The full outer produces a list of all Person/Activity pairs, the left outer determines whether they have been done 

SELECT p.id, act.activity_id, CASE WHEN pa.id is NULL THEN 1 ELSE 0 END has_done FROM Person p 
     FULL OUTER JOIN (SELECT DISTINCT activity_id FROM Person_Activity) act a 
     LEFT OUTER JOIN Person_Activity on a.activity_id = pa.activity_id and pa.id = p.id 
     WHERE pa.id IN (x,y,z) 

-- Either generate the SQL based on what you need 
SELECT * FROM (QUERY X) WHERE (activity.id = 1 and done = 0 ...) 

-- Or use some aggregate function to generate a summary you can compare to an input value. CONCAT here appends the strings, you'll have to figure out this one for your dialenct 
SELECT p.id FROM (QUERY X) GROUP BY p.id HAVING CONCAT(pa.id + '/' + done + ',') = '1/1,2/0....' 
+0

我要澄清:我不是在寻找,看看他们是否已经完成了一定数量的活动,但一组特定的活动或不活动。 – Christopher 2011-03-02 00:03:10

+0

因此,举例来说,我们每个人的名单已完成的活动1,2,3,而不是4和8? – dfb 2011-03-02 00:05:56

+0

准确地说,我的查询在上面的泛化是顺便的。 – Christopher 2011-03-02 00:09:48