mysql - 排序导致左连接不起作用

标签 mysql greatest-n-per-group

我有两个表,locations 和 locations_contacts。

mysql> describe locations;
+----------------+----------------------------+------+-----+---------+----------------+
| Field          | Type                       | Null | Key | Default | Extra          |
+----------------+----------------------------+------+-----+---------+----------------+
| location_id    | int(4)                     | NO   | PRI | NULL    | auto_increment |
| location_name  | varchar(100)               | YES  |     | NULL    |                |
+----------------+----------------------------+------+-----+---------+----------------+

mysql> describe locations_contacts;
+---------------+--------------+------+-----+---------+----------------+
| Field         | Type         | Null | Key | Default | Extra          |
+---------------+--------------+------+-----+---------+----------------+
| contact_id    | int(6)       | NO   | PRI | NULL    | auto_increment |
| location_id   | int(4)       | YES  |     | NULL    |                |
| contact_name  | varchar(100) | YES  |     | NULL    |                |
+---------------+--------------+------+-----+---------+----------------+

每个位置可以有多个联系人,但第一个输入的联系人(contact_id 编号最小的联系人)被视为主要联系人。我希望能够通过单个查询提取位置名称和主要联系人。这是最初有效的方法:

select a.location_id, a.location_name, b.contact from locations as a
    left join (
        select location_id, contact_name as contact 
        from locations_contacts 
        group by location_id
        ) as b on (a.location_id = b.location_id)
where (location_name like '%wesleyan%' or contact like '%wesleyan%') 
order by location_name;

问题是 locations_contacts 的顺序不一致。在使用 InnoDB 时,它很好,但它现在托管在 ndb 集群设置上,并且左连接内返回的结果顺序不一致,因此如果一个位置有多个联系人,我会得到一个基本上随机的结果。对左连接使用“order by”没有帮助,因为分组发生在排序之前,而且我无法删除 group by 子句,因为我只想为每个返回位置返回一条记录。

谁能帮我解决这个问题?过去一天左右的时间里,我一直在为这件事操碎心思,但我并没有多少空闲时间。

最佳答案

我想我们这里需要两个连接。第一个加入类似于您在问题中的子查询。不同之处在于它会为每个位置找到最低的 contact_id。但是您需要联系人姓名,而不是 ID,因此我们可以对 locations_contacts 表进行另一个连接以引入 contact_name

select
    a.location_id,
    a.location_name,
    c.contact_name
from locations as a
left join
(
    select location_id, min(contact_id) as min_contact_id 
    from locations_contacts 
    group by location_id
) as b
    on a.location_id = b.location_id
inner join locations_contacts c
    on b.location_id = c.location_id and
       c.contact_id = b.min_contact_id
where
    a.location_name like '%wesleyan%' or
    c.contact_name like '%wesleyan%'
order by a.location_name;

关于mysql - 排序导致左连接不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46348265/

相关文章:

mysql - 连接到 MySQL 中另一个表中的第 n 个最高值

sql - 根据日期连接表

mysql - 调用函数时执行速度非常慢

sql - FirebirdSQL Unique & Max(或 MaxValue)

mysql - 针对查询的通配符匹配导致分数 = 0 (php/sql)

php - 仅从数据库中选择随机条目一次

sql查询获取每个id的最新记录

r - 在给定列上聚合数据框并显示另一列

php - 将字符串转换为数组并从该数组中获取值

mysql - sql中插入、删除、更新时会发生什么?