Mysql 在现有人员列表中查找0-n行不同类型的人员

Mysql 在现有人员列表中查找0-n行不同类型的人员,mysql,sql,Mysql,Sql,我有一个具有唯一ID“ID”的人员表。这些人执行的活动存储在people_活动表中,表中有“type”activity type列、一个整数和与此人匹配的“id”。我有一个查询,在这个查询中,我会一次撤回许多人,但我想在该查询中添加一个人执行或不执行0个或更多活动的条件 如果我查询一个人,这将是一个简单的例子,其中people\u activity.type=4和people\u activity.type 12,等等,但是由于我要拉回许多人,我不太确定如何做 我当前的查询使用了一个错误的whe

我有一个具有唯一ID“ID”的人员表。这些人执行的活动存储在people_活动表中,表中有“type”activity type列、一个整数和与此人匹配的“id”。我有一个查询,在这个查询中,我会一次撤回许多人,但我想在该查询中添加一个人执行或不执行0个或更多活动的条件

如果我查询一个人,这将是一个简单的例子,其中people\u activity.type=4和people\u 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

你会看到我目前的做法,如果存在,那么选择*from youth\u activity,type=4是不好的,因为这只是检查是否存在单个类型的4,而不一定针对查询中返回的特定人员。

我不完全清楚你的查询,但听起来你想这样做

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

以下是我基于评论的方法


MySQL对EXISTS有一些性能问题,但从语法上讲,您可能会将EXISTS子查询与主查询关联起来。但是如果你想完成活动1,2,3,而不是4和8,那么


我应该澄清一下:我不想看他们是否完成了一定数量的活动,而是看他们是否完成了一组特定的活动。例如,一份完成活动1、2、3的所有人的名单,不是4和8?没错。顺便说一句,我在你上面的查询中的泛化很好。你知道如何在没有完全外部联接的情况下做到这一点吗?奇怪的是,MySQL不支持这些功能。您可以使用笛卡尔乘积实现大致相同的功能“从表1、表2中选择*”。查询中的a.youthid=3子查询位不是只对单个个体起作用吗?该查询当前会撤回一个大的人员列表。否。correlation和a.youthid=y.rid将子查询计数链接到主查询中的青年。将每个主查询行的每个计数与3进行比较,以满足已完成活动1、2、3的条件。非常好!这确实有效。spintheblack的响应也非常有用,但不幸的是,我无法使用完全外部连接。
-- 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....'
            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)