Выбор из внутреннего запроса во второй раз - PullRequest
0 голосов
/ 05 мая 2019

Практикуя написание SQL-запросов, я заметил, что не могу выполнять запросы в форме, подобной этой:

(1)

SELECT attr1, attr2 FROM
   (SELECT attr1, attr2 FROM ...) AS table     
WHERE attr1 >= ALL
   (SELECT attr1 FROM table)

Идея в (1), что я выбираю из внутреннего запроса с псевдонимом «таблица».Я также хочу добавить предложение WHERE, чтобы применить сравнения и получить желаемый результат запроса.Поэтому я сравниваю атрибут с атрибутами из «таблицы».

В этом конкретном случае я выбираю все атрибуты attr1, которые получают максимальное значение в результате внутреннего запроса, которому присвоен псевдоним «таблицы».

Однако приведенный выше пример не работает, и я получаю сообщение об ошибке.

Я понимаю, что если я сделаю что-то подобное ниже, я получу результат запроса:

(2)

SELECT attr1, attr2 FROM
   (SELECT attr1, attr2 FROM ...) AS alias1   
WHERE attr1 >= ALL
   (SELECT attr1 FROM ...)

, где два внутренних запроса одинаковы, за исключением того факта, что attr2 отсутствует во втором.

Моя единственная проблема с query (2) заключается в том, что если внутренний запрос довольно длинный, то вы по сути копируете и вставляете большой кусоккода для повторного использования в соответствии с предложением WHERE.

Мой вопрос заключается в том, почему запрос (1) недействителен и есть ли более эффективные альтернативы запросу (2).

Ответы [ 2 ]

0 голосов
/ 05 мая 2019

Если вам нужна только одна строка, вы можете использовать ORDER BY и LIMIT:

SELECT attr1, attr2
FROM (SELECT attr1, attr2 FROM ...) t
ORDER BY attr1 DESC
LIMIT 1;

Если вы используете MySQL 8+, вы можете использовать RANK() для получения дубликатов:

SELECT attr1, attr2
FROM (SELECT attr1, attr2,
             RANK() OVER (ORDER BY attr1 DESC) as seqnum
      FROM ...
     ) t
WHERE seqnum = 1;

В более ранних версиях вам нужно либо повторить подзапрос, либо использовать переменные.

0 голосов
/ 05 мая 2019

Запрос 1 недействителен, так как предложение SELECT и столбец строятся динамически с использованием подзапроса a, выполненного после выражения FROM и WHERE

, поэтому таблица недоступна в момент выполнения выбора.

второй, не должен быть допустимым для присутствия псевдонима в столбце where, часть для этого

   SELECT attr1, attr2 
FROM
   (SELECT attr1, attr2 FROM ...) AS alias1   
WHERE attr1 >= ALL
   (SELECT attr1 FROM ...) 

действительна, потому что в предложении select подзапроса нет псевдонима

но, обращаясь к вашему коду, вы должны проверить, если вместо suqbery для select и где вы можете выполнить рефакторинг, вы запрашиваете как объединенный запрос

SELECT attr1, attr2 
FROM your_table 
(
  SELECT attr1, attr2 
  FROM your_table 
  WHERE  .... ) AS alias1   
WHERE alias1.attr1   >= your_table.att1
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...