#mysql #sql
#mysql #sql
Вопрос:
Я довольно новичок в MySQL и SQL в целом и не могу полностью понять, как и где размещать псевдонимы. Например, у меня есть схема, подобная этой:
CREATE DATABASE testdb;
USE testdb;
CREATE TABLE table_a (
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
value INT NOT NULL,
PRIMARY KEY(id)
);
CREATE TABLE table_b (
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
value INT NOT NULL,
PRIMARY KEY(id)
);
INSERT INTO table_a (value) VALUES (25), (43), (15);
INSERT INTO table_b (value) VALUES (11), (15), (16);
И мне нужно получить сумму значений каждой записи (в обеих таблицах). Для данного примера это должно быть 125. Мой запрос выглядит так
SELECT SUM(value) FROM
(
SELECT * FROM
(SELECT value FROM table_a) AS a_value
UNION ALL
(SELECT value FROM table_b) #AS b_value
) as total;
Чего я не могу понять, так это:
- почему псевдонимы «a_value» и «total» абсолютно необходимы (я никогда не использую их в этом запросе), а их отсутствие дает мне «Каждая производная таблица должна иметь свой собственный псевдоним»?
- почему «b_value» выдает ошибку «ВЫБОР недопустим в этой позиции» для первого выбора? Разве это не производная таблица, подобная таблице с псевдонимом «a_value»?
И у меня есть один вопрос о круглых скобках и подзапросах: зачем мне нужен этот «SELECT * FROM», чтобы использовать ОБЪЕДИНЕНИЕ в круглых скобках? Я начал с такого запроса:
SELECT SUM(value) FROM
(SELECT value FROM table_a) AS a_value
UNION ALL
(SELECT value FROM table_b);
Но вместо суммы, которую я хочу, чтобы она давала мне сумму «значения» из «table_a», объединенную со столбцом «значение» из «table_b» — [83, 11, 15, 16]. Итак, я попытался просто взять все после FROM в скобках, и это не сработало: я получил ошибку «ВЫБОР недопустим в этой позиции».
Я не был уверен, просто попробовал первое, что пришло мне в голову, и поставил этот SELECT * ИЗ внутренних скобок перед всем остальным, и это сработало. Итак, я хочу знать, почему это работает и почему мой первый способ (только с круглыми скобками) не работает?
Комментарии:
1. Я не совсем понимаю, на какой вопрос вы на самом деле хотите получить ответ
2. Для выбора ОБЪЕДИНЕНИЯ не нужны ни скобки, ни псевдонимы.
Ответ №1:
Все производные таблицы — подзапросы в FROM
предложении — должны иметь псевдоним таблицы. Это не имеет значения, если они когда-либо использовались.
Однако подзапросы не нужны. Вы можете поместить UNION ALL
в FROM
предложение:
SELECT SUM(value) as total
FROM (SELECT value FROM table_a UNION ALL
SELECT value FROM table_b
) ab
-------^ note that this is needed although it is not used in the query
Псевдоним может быть использован:
SELECT SUM(ab.value) as total
Может быть немного быстрее сначала выполнить агрегацию в подзапросе:
SELECT SUM(value)
FROM (SELECT SUM(value) as value FROM table_a UNION ALL
SELECT SUM(value) as value FROM table_b
) ab
Комментарии:
1. Кажется нелогичным, что две (или три) суммы будут быстрее, чем одна, но, похоже, это действительно так — примерно в два раза быстрее примерно на 100 000 строк в таблице
Ответ №2:
Это потому, что результат подзапроса может быть однозначно идентифицирован. Вы должны сделать это, даже если вы не собираетесь нигде ссылаться на имя.
Когда подзапросы используются в операторе SELECT, они могут возвращать только одно значение.
В общем случае подзапрос выполняется только один раз для всего запроса, а его результат используется повторно.
Комментарии:
1. » Когда подзапросы используются в операторе SELECT, они могут возвращать только одно значение » — это неправильно, если вы не имели в виду «в списке выбора» (т. Е. Список столбцов)
2. Вы можете перейти по этой ссылке: » essentialsql.com /. …»