2011-03-01 97 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