MySQL: сортировка на основе другой таблицы соединений, которая не всегда имеет совпадающие значения - PullRequest
0 голосов
/ 03 мая 2018

Вот пользовательский случай, который у меня есть:

Существуют агентства, которые могут иметь одно или несколько мест. Они могут купить подписку для каждого местоположения и для рейтинга (рейтинг - это целое число от 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) не учитывается местоположение

Любые подсказки были бы очень благодарны, большое спасибо!

Ответы [ 2 ]

0 голосов
/ 04 мая 2018

Ах, нашел решение:

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

Ключом было добавить «AND s.location_id = [some_id]» в операторе LEFT JOIN. Он возвращает рейтинг только для этого местоположения и избегает записи дубликатов, поскольку для каждого местоположения существует только один рейтинг.

0 голосов
/ 03 мая 2018
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. Попробуйте сами, надеюсь, у вас есть основная идея. удачи!

...