简体   繁体   English

计入联接

[英]counting in joins

I have many to many association between contact and project . 我在contactproject之间有很多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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM