订购结果左连接不起作用

时间:2017-09-21 15:50:30

标签: mysql greatest-n-per-group

我有两个表,位置和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子句,因为我只想为每个返回的位置记录一条记录。

任何人都可以帮我吗?在最后一天左右,我一直在撕扯我的头发,而且我没有太多的余地。

2 个答案:

答案 0 :(得分:2)

我认为我们需要两个联接。第一个连接到子查询,类似于您在问题中的内容。不同之处在于它找到每个位置的最低$scope.SaveButton = function(){ var postRequest = $http({ method: "POST", url: "http://localhost:5000/licenses", dataType: 'json', data : { name: $scope.name, count: $scope.count, buyDate: $scope.buyDate, licenseType: $scope.licenseType.licenseTypeId }, headers: { "Content-Type": "application/json"} }); postRequest.error(function (data, status){ $window.aler(data.Message); }) } 。但是您需要联系人姓名,而不是ID,因此我们可以再次加入for key, value in request.session.items(): print('{} => {}'.format(key, value)) 表格以引入contact_id

locations_contacts

答案 1 :(得分:0)

我不确定这是最干净的解决方案,但应该可以使用两个连接。第一个获得组的最小值,第二个获得联系。类似的东西:

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