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

8ljdwjyq  于 2021-06-20  发布在  Mysql
关注(0)|答案(2)|浏览(334)

考虑下表:

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   |

我怎样才能得到在licenses表中只有一个相关行并且值为“car”的人(在我们的例子中:吉姆·史密斯)
谢谢

rpppsulh

rpppsulh1#

这应该有助于说明这个过程。。。

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 |
   +----+-----------+----------+------+-------+
xxhby3vn

xxhby3vn2#

你的问题的第一部分很简单(让一个人在一行中只有一个相关联的行) licenses 表)。你只要做一个 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

你的问题的第二部分是一个小把戏:对于只有一张驾照的人来说,他们有一张汽车驾照。为此,可以将过滤器应用于 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子句中应用聚合函数。但是,既然您已经知道所有这些人只有一个许可证,那么 MIN 其实没什么区别(你甚至可以 MAX 结果相同)。

相关问题