Я новичок в MySQL, и благодаря большой поддержке со стороны вас, более опытные ребята, мне удается справиться с трудностями, при этом я многому научился.
У меня есть запрос, который делает именно то, что я хочу. Однако мне это кажется очень запутанным, и я уверен, что должен быть способ упростить его.
Как можно улучшить и оптимизировать этот запрос для повышения производительности?
Большое спасибо
$sQuery = "
SELECT SQL_CALC_FOUND_ROWS ".str_replace(" , ", " ", implode(", ", $aColumns))."
FROM $sTable b
LEFT JOIN (
SELECT COUNT(*) AS projects_count, a.songs_id
FROM $sTable2 a
GROUP BY a.songs_id
) bb ON bb.songs_id = b.songsID
LEFT JOIN (
SELECT AVG(rating) AS rating, COUNT(rating) AS ratings_count, c.songid
FROM $sTable3 c
GROUP BY c.songid
) bbb ON bbb.songid = b.songsID
LEFT JOIN (
SELECT c.songid, c.userid,
CASE WHEN EXISTS
(
SELECT songid
FROM $sTable3
WHERE songid = c.songid
) Then 'User Voted'
else
(
'Not Voted'
)
end
AS voted
FROM $sTable3 c
WHERE c.userid = $userid
GROUP BY c.songid
) bbbb ON bbbb.songid = b.songsID
РЕДАКТИРОВАТЬ: Вот описание того, что делает запрос: -
У меня есть три таблицы:
$ sTable = таблица песен (songid, mp3link, artwork, useruploadid и т. д.)
$ sTable2 = таблица проектов со связанными с ними песнями (projectid, songid, название проекта и т. д.)
$ sTable3 = таблица рейтингов песен (songid, userid, rating)
Все эти данные выводятся в массив JSON и отображаются в таблице в моем приложении, чтобы предоставить список песен в сочетании с проектами и рейтинговые данные.
Сам запрос выполняет следующие действия в следующем порядке: -
Если кому-то нужны какие-то подробности, пожалуйста, дайте мне знать. Спасибо всем.
РЕДАКТИРОВАТЬ:
Благодаря отличной первой попытке Ауримиса я приближаюсь к гораздо более простому решению.
Это код, который я пробовал на основе этого предложения.
SELECT SQL_CALC_FOUND_ROWS ".str_replace(" , ", " ", implode(", ", $aColumns))."
FROM
(SELECT
$sTable.songsID, COUNT(rating) AS ratings_count,
AVG(rating) AS ratings
FROM $sTable
LEFT JOIN $sTable2 ON $sTable.songsID = $sTable2.songs_id
LEFT JOIN $sTable3 ON $sTable.songsID = $sTable3.songid
GROUP BY $sTable.songsID) AS A
LEFT JOIN $sTable3 AS B ON A.songsID = B.songid AND B.userid = $userid
Однако есть несколько проблем. Мне пришлось удалить первую строку вашего ответа, так как это вызвало внутреннюю ошибку сервера 500:
IF(B.userid = NULL, "Not voted", "User Voted") AS voted
Очевидно, теперь функция «проверки с голосованием» потеряна.
Кроме того, что более важно, он возвращает не все столбцы, определенные в моем массиве, а только songID.Мой JSON возвращает неизвестный столбец «song_name» в «списке полей» - если я удалю его из своего массива $ aColumns, он, конечно, перейдет к следующему.
Я определяю свои столбцы в начале моего скрипта, поскольку этот массив используется для фильтрации и объединения выходных данных для кодирования JSON. Это определение $ aColumns: -
$aColumns = array( 'songsID', 'song_name', 'artist_band_name', 'author', 'song_artwork', 'song_file', 'genre', 'song_description', 'uploaded_time', 'emotion', 'tempo', 'user', 'happiness', 'instruments', 'similar_artists', 'play_count', 'projects_count', 'rating', 'ratings_count', 'voted');
Чтобы быстро проверить остальную часть запроса, я изменил первую строку в подзапросе, выбрав $ sTable. *, А не $ sTable.songsID (помните, что $ sTable - это таблица песен )
Тогда ... Запрос явно работал, но, конечно, с ужасной производительностью. Но вернули только 24 песни из 5000 тестовых данных. Поэтому я изменил ваше первое «JOIN» на «LEFT JOIN», так что все 5000 песен были возвращены. Чтобы прояснить запрос, необходимо вернуть ВСЕ строки в таблице песен, но с различными дополнительными битами данных из проектов и таблиц рейтингов для каждой песни.
Итак ... Мы приближаемся, и я уверен, что это намного лучший подход, он просто требует некоторой модификации. Спасибо за вашу помощь, Ауримис.