Выберите поля, которых нет в выбранных полях - MySQL - PullRequest
1 голос
/ 09 марта 2019

У меня в таблице содержатся песни. Я хочу выбрать топ 3 из самых любимых песен и 3 из случайных песен, которых нет в первой в одном запросе.

например: table of songs и ожидаемый результат:

song 6, song 8, song 5 then *whatever song*,*whatever song*,*whatever song*

Вот что я пробовал, но не работает:

SELECT a.`song_id`, a.`name`, a.liked, b.song_id 
FROM `song` AS a, 
(SELECT song_id FROM song ORDER BY liked DESC LIMIT 3) as b 
WHERE a.song_id <> b.song_id LIMIT 3 
SELECT
    a.`song_id`, a.`name`, a.liked, b.ids
FROM
    `song` AS a,
    (SELECT substring_index(GROUP_CONCAT(DISTINCT song_id ORDER BY liked DESC SEPARATOR ','), ',', 3) as ids FROM song) as b
WHERE
    a.song_id not in(b.ids)

Я использую MariaDB 10.1.29, он не совместим с LIMIT в подзапросе или в предложении WITH.

Ответы [ 3 ]

1 голос
/ 09 марта 2019

Использование 2 CTE с LIMIT работает в MariaDb 10.2 и MySql 8.0

Второй CTE делает это случайным образом, не выбирая те из первого CTE

 WITH TOP3SONGS AS
 (
   SELECT *
   FROM song
   ORDER BY liked DESC
   LIMIT 3
 ),
 RANDOM3SONGS AS
 (
   SELECT *
   FROM song
   WHERE song_id NOT IN (select song_id from TOP3SONGS)
   ORDER BY rand()
   LIMIT 3
 )
 SELECT *
 FROM TOP3SONGS
 UNION ALL
 SELECT *
 FROM RANDOM3SONGS;

И это работает вMySql 5.6, скорее всего, также в MariaDb 10.1.29
(у меня нет доступа к 10.1, поэтому я не могу проверить)

На этот раз используется левое соединение с топ3.
И порядок по ставит top3 выше случайного числа перед пределом 6.

SELECT song.*
FROM song
LEFT JOIN 
(  SELECT song_id, liked 
   FROM song 
   ORDER BY liked DESC 
   LIMIT 3
) top3songs ON top3songs.song_id = song.song_id
ORDER BY top3songs.liked DESC, RAND()
LIMIT 6;

Тест на db <> fiddle здесь

0 голосов
/ 11 марта 2019

На данный момент у меня установлена ​​только MariaDB 10.3, но я попробовал приведенный ниже синтаксис на более старой версии MySQL 4.1, и оба возвращают одинаковые результаты.

SELECT * FROM (
(SELECT * FROM song ORDER BY liked DESC LIMIT 3) UNION
(SELECT A.* FROM song A LEFT JOIN (SELECT * FROM song ORDER BY liked DESC LIMIT 3) B ON A.song_id=B.song_id 
WHERE B.song_id IS NULL ORDER BY RAND() LIMIT 3)) S ORDER BY liked DESC;
0 голосов
/ 09 марта 2019

Вы должны разделить его на два и объединить результаты: первый запрос для выбора первых 3:

SELECT song_id FROM song ORDER BY liked DESC LIMIT 3

второй запрос для выбора случайных трех, не включая выбранные выше песни:

SELECT song_id FROM song WHERE song_id NOT IN (
   SELECT song_id FROM song ORDER BY liked DESC LIMIT 3
) ORDER BY RAND() LIMIT 3

и все вместе сейчас:

SELECT song_id FROM song ORDER BY liked DESC LIMIT 3
UNOION
SELECT song_id FROM song WHERE song_id NOT IN (
   SELECT song_id FROM song ORDER BY liked DESC LIMIT 3
) ORDER BY RAND() LIMIT 3
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...