订购导致左联接不起作用

订购导致左联接不起作用

我有两张桌子,位置和位置联系人。

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

每个位置可以有多个联系人,但输入的第一个联系人(编号最低的联系人)被视为主要联系人。我希望能够通过一个查询拉取位置名和主要联系人。这就是最初的效果:
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;

问题是,地点和联系人的顺序不一致。在使用InnoDB的时候,这是很好的,但是现在它被托管在ndb集群设置上,并且在左连接中返回的结果是不一致的,所以如果一个位置有多个联系人,我得到的结果基本上是随机的。对左连接使用“order by”没有帮助,因为分组是在可以对其进行排序之前发生的,而且我不能消除groupby子句,因为我只希望返回每个位置的一条记录。
有人能帮我吗?在这件事上,我已经把头发扯了一天左右了,可我没有多少空闲时间。

最佳答案

我想我们需要两个接头。第一个连接到子查询,类似于您在问题中的查询。不同之处在于,它为每个位置找到了最低的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/

10-09 21:55