Куда помещать псевдонимы в запросе MySQL

#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;
  

Чего я не могу понять, так это:

  1. почему псевдонимы «a_value» и «total» абсолютно необходимы (я никогда не использую их в этом запросе), а их отсутствие дает мне «Каждая производная таблица должна иметь свой собственный псевдоним»?
  2. почему «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 /. …»