Ищем 0-н ряды разных типов в существующем списке людей - PullRequest
0 голосов
/ 02 марта 2011

У меня есть таблица людей с уникальным идентификатором 'id'. Действия, выполняемые этими людьми, хранятся в таблице people_activity со столбцами «type» (тип действия, целое число) и «id», которые соответствуют человеку. У меня есть запрос, в котором я зацикливаюсь на множестве людей одновременно, но я бы хотел добавить к этому запросу условия, при которых человек выполняет или не выполняет 0 или более действий.

Если бы я опрашивал одного человека, это было бы просто "где people_activity.type = 4 и people_activity.type <> 12" и т. Д., Но так как я оттягиваю многих людей, я не совсем уверен, как это сделать.

Мой текущий запрос с неверным предложением where для типа (извините, я упростил его в своем объяснении):

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 существует вообще, и не обязательно для конкретные люди вернулись в запросе.

Ответы [ 2 ]

1 голос
/ 02 марта 2011

MySQL имеет некоторые проблемы с производительностью в EXISTS, но синтаксически вы бы сопоставили подзапрос EXISTS с основным запросом.Но если вы хотите 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)
1 голос
/ 02 марта 2011

Мне не совсем понятно из вашего запроса, но звучит так, как будто вы хотите сделать что-то вроде этого

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....'
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...