MySQL查询:GROUP_CONCAT

时间:2011-11-18 08:36:19

标签: mysql subquery

我需要帮助构建查询。

我有两张桌子。一个叫做jobs_certs,另一个称为users_certs。

jobs_certs表包含申请作业所需的证书。每个必需的证书都有自己的行,job_id表示附加了所需证书的作业,而cert_id表示附加到该证书的id。

users_certs表包含用户拥有的所有证书。每个证书都有自己的行,uid表示用户的id,cert_id表示用户拥有的证书的id。

我需要查看用户是否拥有该作业所需的所有证书。所以我试过这样的事情:

SELECT GROUP_CONCAT(cert_id) as certs, uid 
FROM users_certs 
HAVING certs = (SELECT GROUP_CONCAT(cert_id) FROM jobs_certs WHERE job_id = 6)

但我没有得到任何结果。我应该怎么做呢?

提前致谢。

2 个答案:

答案 0 :(得分:0)

放手一搏。为作业证书创建内联视图,为用户证书创建另一个视图,然后在inner join列表中cert_id创建order by(确保GROUP_CONCAT中有GROUP_CONCAT制作select users.uid from (SELECT GROUP_CONCAT(cert_id order by cert_id asc) as certs, uid FROM users_certs group by uid) users inner join (SELECT GROUP_CONCAT(cert_id order by cert_id asc) as certs, job_id FROM jobs_certs where job_id = 6 group by job_id) jobs on jobs.certs = users.certs; 确定性的结果:

hasRequiredCerts

或者您甚至可以将查询装扮一点,以便返回所有用户,无论他们是否具有select users.uid,case when job_id is null then 'No' else 'Yes' end as hasRequiredCerts from (SELECT GROUP_CONCAT(cert_id order by cert_id asc) as certs, uid FROM users_certs group by uid) users left join (SELECT GROUP_CONCAT(cert_id order by cert_id asc) as certs, job_id FROM jobs_certs where job_id = 6 group by job_id) jobs on jobs.certs = users.certs; 列所需的证书:

{{1}}

答案 1 :(得分:0)

关系模型的一个原则是列值应该简单而不是复合;在白话中,它被称为first normal form(1NF)。虽然有GROUP_CONCAT的有效用途(产生的关系不是1NF),但它会让你绊倒。相反,请关注所需的结果:选择用户缺少作业的证书。您可以使用证书ID上的左连接或右连接来执行此操作,选择用户为NULL的那些行。

SELECT jc.cert_id
    FROM jobs_certs AS jc
    LEFT JOIN users_certs AS uc ON jc.cert_id = uc.cert_id
    WHERE jc.job_id = ? AND uc.cert_id IS NULL

如果没有遗漏认证,则用户完全合格。或者,您可以选择COUNT(jc.cert_id)以获取缺失证书的数量。