[英]counting in joins
I have many to many association between contact
and project
. 我在
contact
和project
之间有很多contact
。
contact:
+-----------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| deleted | boolean | NO | | NULL | |
+-----------------+--------------+------+-----+---------+----------------+
project:
+-----------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| status | varchar | NO | | NULL | |
+-----------------+--------------+------+-----+---------+----------------+
project_contact:
+---------------+---------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+---------------+---------+------+-----+---------+-------+
| project_id | int(11) | NO | PRI | NULL | |
| contact_id | int(11) | NO | PRI | NULL | |
| proj_con_role | varchar | NO | | NULL | |
+---------------+---------+------+-----+---------+-------+
I would like to count how many contacts are associated with no projects, one project or more than one project. 我想计算有多少个联系人与一个项目,一个项目或多个项目相关联。 But, for those 2 latter (one project and more than one project) the project status has to be
'STATUS_X'.
但是,对于后两个(一个项目和一个以上项目),项目状态必须为
'STATUS_X'.
The proj_con_role
has to be 'CLIENT'
and also, the contact must not be marked as deleted. proj_con_role
必须为'CLIENT'
,并且该联系人也不得标记为已删除。 If I could get that in one single query, that'd be absolutely awesome, if not, 3 different queries would do as well. 如果我可以在一个查询中得到它,那绝对是很棒的,否则,三个不同的查询也可以。
I have this so far: 到目前为止,我有:
SELECT numprojects,
Count(*) AS numcontacts
FROM (
SELECT c.id,
Count(pc.contact_id) AS numprojects
FROM contact c
LEFT JOIN project_contact pc
ON pc.contact_id = c.id
AND pc.proj_con_role = 'CLIENT'
WHERE (
c.deleted isnull
OR c.deleted = false)
GROUP BY c.id ) c
GROUP BY numprojects
ORDER BY numprojects
Now, this works fine, but for the life of me, I cannot seem to add the condition that the project has to have a certain status... I have no idea how to add it. 现在,这可以正常工作,但是对于我一生来说,我似乎无法添加该项目必须具有一定状态的条件……我不知道如何添加它。 Any help would be absolutely great.
任何帮助都是绝对伟大的。
I have tried adding: 我尝试添加:
left join project p on p.status = 'STATUS_X' and p.id = pc.project_id
but of course, it doesn't work like this... 但是,当然,它不能像这样...
later edit 1: 以后编辑1:
if I add: 如果我添加:
inner join project p on p.status = 'STATUS_X' and p.id = pc.project_id
I get the correct results for 1 or more projects, but the contacts on no projects are ignored. 对于1个或多个项目,我得到了正确的结果,但是没有项目上的联系人被忽略。 Maybe a union here?
也许这里有工会? Not sure.
不确定。
This should work: 这应该工作:
select
case when project_contracts = 0 then '0 projects'
when project_contracts = 1 then '1 project'
else '2+ projects' end as num_of_projects
count(contracts) as contracts
from
(select
c.id as contracts
sum(case when p.id is null then 0 else 1 end) as projects_contracts
from contracts c
left join project_contracts p on p.id = c.id
group by c.id)
group by case when project_contracts = 0 then '0 projects'
when project_contracts = 1 then '1 project'
else '2+ projects' end
List contracts wth Null on contracts (with no contracts) 列出合同中没有合同的合同(无合同)
SELECT *
FROM contact c
LEFT JOIN project_contact pc --Left join = all contacts, even if no join to a contract is made
ON pc.contact_id = c.id
AND pc.proj_con_role = 'CLIENT'
WHERE (c.deleted isnull
OR c.deleted = false)
AND pc.id isnull --Clients with no contacts
For contacts with contracts 对于合同合同
SELECT *
FROM contact c
INNER JOIN project_contact pc --Inner join only shows succesful joins (meaning neither ID can be null)
ON pc.contact_id = c.id
AND pc.proj_con_role = 'CLIENT'
WHERE (c.deleted isnull
OR c.deleted = false)
AND pc.status = 'Status_X' --your status
I can't test the code, but what you need is Left Join for null contracts and Inner join to find all matches, then filter based on status. 我无法测试代码,但是您需要的是使用Left Join进行空合同,使用Inner join查找所有匹配项,然后根据状态进行过滤。
Both codes I listed only select the records/joins, so you'd have to use the results in any way you need (count, I assume). 我列出的两个代码都只选择记录/联接,因此您必须以所需的任何方式使用结果(我认为是计数)。
I fixed it this way: 我用这种方式解决了:
SELECT numprojects,
Count(*) AS numcontacts
FROM (
SELECT c.id,
Count(pc.contact_id) AS numprojects
FROM contact c
LEFT JOIN project_contact pc
ON pc.contact_id = c.id
AND pc.proj_con_role = 'CLIENT'
INNER JOIN project p
ON p.status = 'STATUS_X'
AND p.id = pc.mandate_id
WHERE (
c.deleted isnull
OR c.deleted = false)
GROUP BY c.id ) c
GROUP BY numprojects
UNION ALL
SELECT numprojects,
count(*) AS numcontacts
FROM (
SELECT c.id,
count(pc.contact_id) AS numprojects
FROM contact c
LEFT JOIN project_contact pc
ON pc.contact_id = c.id
AND pc.project_contact_role = 'CLIENT'
WHERE (
c.deleted isnull
OR c.deleted = false)
GROUP BY c.id ) c
WHERE numprojects = 0
GROUP BY numprojects
ORDER BY numprojects
Thank you all for your answers and support. 谢谢大家的回答和支持。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.