Разобьем два запроса к двум таблицам, каждая из которых содержит два столбца.Во-первых, мы сделаем простое:
SELECT t1.a,t2.d + 6 as e
FROM
table1 t1
inner join
table2 t2
on
t1.a = t2.c
WHERE
t1.b = 2
ORDER BY
t2.c
И давайте посмотрим, что находится "в области действия", когда мы завершим каждое предложение:
FROM table1 t1
-на данный момент у нас есть набор результатов, содержащий два столбца - {t1.a, t1.b}
.
INNER JOIN table2 t2 ON ...
- теперь у нас есть набор результатов, содержащий четыре столбца - T1.a, t1.b, t2.c, t2.d}
.Лично мы можем теперь также сказать, что a
и c
равны, но это не имеет значения для анализа.
WHERE
- хотя WHERE
может фильтровать строки из запроса, он не меняет набор столбцов, составляющих набор результатов - он по-прежнему {t1.a, t1.b, t2.c, t2.d}
.
SELECT
- у нас нет GROUP BY
и, следовательно, задача SELECT
здесь состоит в том, чтобы a) пометить некоторые столбцы для вывода и b) возможно добавить некоторые дополнительные столбцы, значения которых вычисляются.Это то, что мы имеем здесь.В итоге мы получаем набор {O(t1.a), t1.b, t2.c, t2.d, O(e = t2.d +6)}
1 .
ORDER BY
- теперь мы заказываем по t2.c
, который все еще находится в области применения, несмотря на то, чточто он не будет выводиться
наконец, выходные данные этого запроса доставляются (технически через курсор) и просто содержат {a, e}
.У столбцов больше нет связанной с ними «исходной таблицы», а столбцы без вывода исчезают в эфире.
SELECT
t1.a,SUM(t2.d) as e
FROM
table1 t1
inner join
table2 t2
on
t1.a = t2.c
GROUP BY t1.a
HAVING e > 5
ORDER BY t1.a
Пункты FROM
/ JOIN
идентичны предыдущим, и поэтому преобладает тот же анализ.Точно так же у нас нет предложения WHERE
, но оно не имеет отношения к набору столбцов.У нас есть {t1.a, t1.b, t2.c, t2.d}
.
SELECT
/ GROUP BY
/ DISTINCT
.DISTINCT
и GROUP BY
на самом деле одно и то же - оба идентифицируют набор столбцов либо явно (GROUP BY
), либо по их существованию в предложении SELECT
.Вы не можете отвязать SELECT
от GROUP BY
, потому что нам также нужно вычислить агрегаты , а определения агрегатов содержатся в предложении SELECT
.Для каждого отдельного набора значений, видимых в столбцах группировки, мы создаем одну выходную строку, содержащую этот набор значений вместе с любыми вычисленными агрегатами.Здесь мы выдаем {O(t1.a), O(e)}
2 и , что является результирующим набором, который могут наблюдать оставшиеся части запроса.Исходный набор результатов не находится в области действия.
HAVING
- мы можем работать только с теми столбцами, которые получены в предложении SELECT
3 .Но опять же, мы фильтруем строки , а не столбцы.
и ORDER BY
также могут работать только со столбцами, созданными в SELECT
.
К тому времени, когда SELECT
было сделано, у нас все равно были только выходные столбцы, но обработка вывода в любом случае была такой же.
Надеюсь, изВы можете увидеть, что SELECT
может работать двумя совершенно разными способами;но, по крайней мере, теперь вы знаете о разнице и побочных эффектах этого.
1 Я здесь на лету придумываю терминологию, ноЯ использую оболочку O()
для обозначения «этот столбец будет в окончательном наборе результатов».
2 Это поведение, которое вы ожидаете от SELECT
всегда демонстрировать, предоставляя только «исходящие» строки для последующих предложений.
3 mysql содержит расширение стандарта SQL, которое позволяет группировать и не агрегироватьстолбцы отображаются как предикаты предложения HAVING
.Они фактически переписаны для использования в предложении WHERE
.