MySQL:基于另一个并不总是具有匹配值的连接表进行排序

Posted

技术标签:

【中文标题】MySQL:基于另一个并不总是具有匹配值的连接表进行排序【英文标题】:MySQL: sorting based on another join table that doesn't always have matching values 【发布时间】:2018-10-13 07:26:17 【问题描述】:

这是我的用户案例:

有些机构可以有一个或多个位置。 他们可以为每个位置和排名购买订阅(排名是 1 到 5 之间的整数)。因此,一个代理机构可以有多个订阅(每个位置最多一个)

这是表格:

agency: id, name
location: id, name
agency_location: agency_id, location_id
subscription: id, agency_id, location_id, ranking

到目前为止一切顺利,非常简单。

然后我想显示给定位置的所有代理商(例如,location_id = 9),并按此位置的排名对它们进行排序(知道某些代理商不会订阅 - 即没有排名,应该来在确实有订阅的人之后)。

我尝试了各种 SQL 语句,但似乎无法弄清楚......

例如:

SELECT * FROM agencies
LEFT JOIN subscription ON subscription.agency_id=agency.id
ORDER BY (subscription.ranking IS NULL) ASC, subscription ranking ASC

将返回所有代理商,其中订阅排名靠前的代理商。

但是, 1) 如果代理有多个订阅,则返回重复值,并且 2)它没有考虑位置

任何线索将不胜感激,非常感谢!

【问题讨论】:

【参考方案1】:

啊,找到解决办法了:

SELECT a.* FROM agencies a
LEFT JOIN subscription s ON s.agency_id=a.id AND s.location_id=[some_id]
ORDER BY (s.ranking IS NULL) ASC, s.ranking ASC

关键是在 LEFT JOIN 语句中添加“AND s.location_id=[some_id]”。它既返回该位置的排名,又避免重复记录,因为每个位置只有一个排名。

【讨论】:

【参考方案2】:
SELECT * FROM agencies a
LEFT JOIN subscriptions s ON s.agency_id = a.id
WHERE s.location_id = 9 ORDER BY s.ranking ASC

此查询将为您提供按 ranking 排序的某个位置的代理商列表 = 9。没有订阅的代理商将排在下面,因为它们的排名将是 NULL。但是,当机构有多个订阅时,此查询的结果可能包含重复项。

你必须在结果上做group by,比如

SELECT * FROM (
  SELECT * FROM agencies a
  LEFT JOIN subscriptions s ON s.agency_id = a.id
  WHERE s.location_id = 9 ORDER BY s.ranking ASC
) as tempTable GROUP BY a.id

或者您可以再次将结果作为 tempTable 和 left join 代理表,然后再创建为 group by。自己试试吧,我希望你有主要的想法。祝你好运!

【讨论】:

感谢您的提示,非常感谢。但是,我认为这不太正确,因为没有订阅的代理商会首先出现(这就是为什么在我的示例中我必须添加 (subscription.ranking IS NULL) 部分

以上是关于MySQL:基于另一个并不总是具有匹配值的连接表进行排序的主要内容,如果未能解决你的问题,请参考以下文章

MySQL触发器将日期插入具有唯一匹配ID的行

MySQL 并不总是使用具有相同查询的键

基于另一个值的具有多种对象类型的可编码解码属性

添加具有基于另一个日期时间列的值的日期时间列

添加具有基于从文件名中提取的日期的值的列(值的长度 (1) 与索引的长度 (50) 不匹配)

具有正确地址但具有另一个随机值的 C++ 指针?