获取联接表中只有1个匹配行的记录?

时间:2018-07-17 14:51:18

标签: mysql

请考虑以下表格:

Persons  
|id   |firstname|lastname|  
|-----|---------|--------|  
|1    |John     |Doe     |  
|2    |Jim      |Smith   |  
|3    |Jane     |Boggard |  
|4    |Joe      |Dash    |  

Licences
|p_id |licence|
|-----|-------|
|1    |car    |
|1    |bike   |
|2    |car    |
|3    |car    |
|3    |bike   |
|1    |plane  |
|4    |bike   |

如何获得许可证表中只有1个关联行且值为“ car”的人员? (在我们的示例中:吉姆·史密斯)

谢谢

2 个答案:

答案 0 :(得分:0)

问题的第一部分非常简单(在licenses表中得到一个只有1个关联行的人)。您只需先执行GROUP BY,然后执行HAVING COUNT(*) = 1

select
    persons.id
  ,persons.firstname
  ,Persons.lastname
from Persons
    inner join Licenses on
        Licenses.p_id = Persons.`id`
group by
    persons.id
    ,persons.firstname
    ,persons.lastname
having 
  count(*) = 1

问题的第二部分有些棘手:对于只有1个驾照且拥有驾照的人。为此,您可以将过滤器应用于HAVING子句,因此它将在group by之后应用。例如(请注意最后一行):

select
    persons.id
  ,persons.firstname
  ,Persons.lastname
from Persons
    inner join Licenses on
        Licenses.p_id = Persons.`id`
group by
    persons.id
    ,persons.firstname
    ,persons.lastname
having 
  count(*) = 1
  and min(licenses.licence) = 'car'

您正在使用MIN函数,因为通常需要在HAVING子句中应用聚合函数。但是,由于您已经知道所有这些人仅拥有1个许可证,因此MIN并没有真正改变(您甚至可以使用MAX获得相同的结果)。

答案 1 :(得分:0)

这应该有助于说明该过程...

SELECT p.*, SUM(l.licence = 'car') cars, COUNT(*) total
  FROM persons p
  JOIN licences l
    ON l.p_id = p.id
 GROUP
    BY p.id;
   +----+-----------+----------+------+-------+
   | id | firstname | lastname | cars | total |
   +----+-----------+----------+------+-------+
   |  1 | John      | Doe      |    1 |     3 |
   |  2 | Jim       | Smith    |    1 |     1 |
   |  3 | Jane      | Boggard  |    1 |     2 |
   |  4 | Joe       | Dash     |    0 |     1 |
   +----+-----------+----------+------+-------+