MySQL возвращает первую строку объединенной таблицы - PullRequest
9 голосов
/ 05 марта 2012

У меня есть две таблицы (страна и утки), где в таблице стран указаны все страны мира, а в таблице уток - список уток с полем country_id для ссылки на основную страну.

I 'я пытаюсь получить список только стран, в которых есть хотя бы одна утка, и с этой единственной записью соответствия из таблицы уток для утки с самой высокой оценкой в ​​этой стране.Пока у меня есть:

SELECT *
FROM country c 
INNER JOIN ducks d ON c.id = d.country_id
ORDER BY c.country ASC, d.rating DESC

Это возвращает список каждой утки, а не только по одной на страну.

Буду признателен, если кто-нибудь сможет указать мне правильное направление здесь.Я предпочел бы сделать это на SQL, чем иметь отдельный запрос для каждой страны, чтобы вытащить утку с самым высоким рейтингом.

Ответы [ 5 ]

19 голосов
/ 05 марта 2012
SELECT c.*, d.*
FROM country c 
  INNER JOIN ducks d 
    ON d.id =                         --- guessing the ducks Primary Key here
       ( SELECT dd.id                 --- and here  
         FROM ducks dd
         WHERE c.id = dd.country_id
         ORDER BY dd.rating DESC
         LIMIT 1
       )

Индекс на (country_id, rating, id) для таблицы MyISAM или (country_id, rating) для таблицы InnoDB, помог бы.

В этом запросе будет показан только один duck на страну, даже если более одного из них имеют одинаковый рейтинг. Если вы хотите, чтобы появлялись утки с привязанным рейтингом, используйте @ imm's GROUP BY answer.

8 голосов
/ 05 марта 2012

Вы можете попробовать просто добавить выбранное объединение, для

SELECT c.*, d.*
FROM country c 
INNER JOIN ducks d ON c.id = d.country_id
LEFT JOIN ducks d2 ON d.country_id = d2.country_id AND d2.rating > d.rating
WHERE d2.id IS NULL
3 голосов
/ 05 марта 2012

Вы можете попробовать:

SELECT c.*, d.*
FROM country c
INNER JOIN (
    SELECT d.country_id, d.id, MAX(d.rating) AS rating
    FROM ducks d
    GROUP BY d.country_id
) q ON (q.country_id = c.id)

INNER JOIN ducks d 
    ON (d.country_id, d.rating) = (q.country_id, q.rating)
0 голосов
/ 05 марта 2012

Попробуйте это:

SELECT c.country, MAX(d.rating) AS max_rating
FROM country c
JOIN ducks d ON c.id = d.country_id
GROUP BY c.id
ORDER BY c.country ASC

Если «наивысший рейтинг» равен 1, то изменить MAX(d.rating) на MIN(d.rating)

0 голосов
/ 05 марта 2012

Многие базы данных имеют некоторый эквивалент "выберите топ 10 * из ...". В mySql синтаксис будет "выбрать * из ... предел 10".

... НО ...

В этом случае вам действительно нужны «group by» и «max ()»!

...