Ответ
Стандартный SQL-запрос для выборки данных (SELECT) состоит из нескольких ключевых блоков, которые пишутся в одном порядке, а выполняются СУБД в другом.
Синтаксис (порядок написания):
SELECT [DISTINCT] column1, column2
FROM table_name
JOIN other_table ON join_condition
WHERE condition
GROUP BY column_name
HAVING condition
ORDER BY column_name [ASC|DESC]
LIMIT count OFFSET-skip;
Назначение блоков:
SELECT: Указывает, какие столбцы вернуть в результате.FROM: Определяет основную таблицу для выборки.JOIN: Объединяет строки из двух или более таблиц на основе связанного столбца.WHERE: Фильтрует записи, оставляя только те, что соответствуют условию.GROUP BY: Группирует строки с одинаковыми значениями в сводные строки.HAVING: Фильтрует сгруппированные данные. В отличие отWHERE, работает после агрегации.ORDER BY: Сортирует результирующий набор.LIMIT / OFFSET: Ограничивает количество возвращаемых строк и указывает, сколько строк пропустить.
Логический порядок выполнения запроса (как его "видит" база данных):
FROM/JOIN: Формирование исходного набора данных.WHERE: Первичная фильтрация строк.GROUP BY: Агрегация данных.HAVING: Фильтрация агрегированных данных.SELECT: Выборка нужных столбцов.ORDER BY: Сортировка результата.LIMIT/OFFSET: Ограничение вывода.
Ответ 18+ 🔞
А, ну вот, опять эти ваши SQL-запросы, блядь! Сидишь, думаешь, что всё просто написал, а оно, сука, не работает, и ты уже готов монитор об стенку ебнуть. А всё потому, что порядок написания и порядок выполнения — это две большие разницы, ёпта!
Смотри сюда, как это обычно пишут, эти распиздяи:
SELECT [DISTINCT] column1, column2
FROM table_name
JOIN other_table ON join_condition
WHERE condition
GROUP BY column_name
HAVING condition
ORDER BY column_name [ASC|DESC]
LIMIT count OFFSET-skip;
Вроде логично, да? Сначала сказал, что хочешь (SELECT), потом откуда (FROM), потом как соединить... Ну, в общем, по понятиям. Но база данных, эта хитрая жопа, читает это всё наоборот, блядь! У неё свой план, как у маньяка.
Вот как она на самом деле это дело в голове раскладывает, по шагам:
-
FROM/JOIN— это самое первое, блядь. Она смотрит: "О, откуда данные-то брать будем? А, вот эти две таблицы склеить надо? Ну давай, склеивай, хуле". Всё начинается отсюда, в рот меня чих-пых! -
WHERE— а вот тут она уже начинает отсеивать мусор. "Так-так, из всей этой кучи склеенного дерьма оставить только то, что под условие подходит. Остальное — нахуй, в помойку". -
GROUP BY— ну а тут уже начинается магия, блядь. "Ага, теперь сгруппируем-ка мы эти отфильтрованные строки в кучки, по братству, так сказать". Сводные строки появляются, ёперный театр! -
HAVING— и вот тут главный подвох, многие на этом обжигаются!WHEREуже отфильтровал ДО группировки, а этот хитрыйHAVINGприходит ПОСЛЕ и говорит: "А теперь, сука, давай проверим эти вот сгруппированные кучи. Эта куча годится, а вот эта — нет, нахуй её". Он работает с результатами агрегации, типаCOUNTилиSUM, понимаешь? -
SELECT— и только сейчас, блядь, когда всё отфильтровали, сгруппировали и ещё раз отфильтровали, база говорит: "А, ну теперь-то я готова показать тебе именно те столбцы, которые ты просил в самом начале!". Вот так вот, всё наизнанку. -
ORDER BY— "Ну и под конец, красава, отсортируем этот красивый результат как тебе надо — по возрастанию или по убыванию". -
LIMIT/OFFSET— финальный аккорд, блядь! "Всё, мудила, насобирал кучу данных? А я тебе дам только десять строк, и ещё первые пять пропущу. На, получай!". Ограничение идёт самым последним.
Вот и весь секрет, блядь. Пишешь ты в одном порядке, а думает она — в другом. Главное — запомнить эту разницу, а то будешь как тот Герасим из рассказа: WHERE пытаться применить к тому, что уже GROUP BY сделал, и нихуя не выйдет, только "Муму..." говорить останется. Пиздец.