Подтвердить что ты не робот

Как повторно использовать столбец результатов в выражении для другого столбца результата

Пример:

SELECT
   (SELECT SUM(...) FROM ...) as turnover,
   (SELECT SUM(...) FROM ...) as cost,
   turnover - cost as profit

Уверен, что это недопустимо (по крайней мере, в Postgres), но как добиться того же в запросе без повторной перезаписи суб-запроса?

4b9b3361

Ответ 1

Так же:

SELECT
   turnover,
   cost,
   turnover - cost as profit
from (
   (SELECT SUM(...) FROM ...) as turnover,
   (SELECT SUM(...) FROM ...) as cost
   ) as partial_sums

Ответ 2

Вы можете повторно использовать запрос следующим образом:

WITH 
  TURNOVER AS (
    SELECT SUM(...) FROM ...)
  ),
  COST AS(
    SELECT SUM(...) FROM ...
  )

SELECT *
FROM(
 SELECT
   TURNOVER.sum as SUM_TURNOVER
 FROM
 TURNOVER,COST
 WHERE ....
) AS a

Это эквивалентно:

SELECT *
FROM(
 SELECT
   TURNOVER.sum as SUM_TURNOVER
 FROM
 (
   SELECT SUM(...) FROM ...)
 )AS TURNOVER,
 (
   SELECT SUM(...) FROM ...
 )AS COST
 WHERE ....
) AS a

Здесь стоит отметить. Первый метод более читабельный и многоразовый, но второй метод может быть быстрее, потому что БД может выбрать лучший план для него.

Ответ 3

Возможно, предложение sql "with" могло бы помочь, как представлено здесь http://orafaq.com/node/1879 (другие базы данных, такие как Postgres, также делают это, а не просто оракул).

Ура! Андре

Ответ 4

На самом деле я много работал над этим и ударил по многим кирпичным стенам, но, наконец, понял ответ - больше взлома - но он работал очень хорошо и уменьшил накладные расходы на мои запросы на 90%....

Поэтому вместо того, чтобы многократно дублировать коррелированный запрос для извлечения нескольких столбцов из подзапроса, я просто использовал concat все значения, которые я хочу вернуть в разделенный запятой varchar, а затем разворачивать их снова в приложении...

Итак, вместо

select a,b,
(select x from bigcorrelatedsubquery) as x,
(select y from bigcorrelatedsubquery) as y,
(select z from bigcorrelatedsubquery) as z
from outertable

Теперь я делаю

select a,b,
(select convert(varchar,x)+','+convert(varchar,x)+','+convert(varchar,x)+',' 
from bigcorrelatedsubquery) from bigcorrelatedquery) as xyz
from outertable
group by country

Теперь у меня есть все три коррелированные "скалярные" значения, которые мне нужны, но мне нужно было выполнить только коррелированный подзапрос один раз вместо трех раз.

Ответ 5

SELECT turnover, cost, turnover - cost
FROM
(
SELECT
(SELECT ...) as turnover,
(SELECT ...) as cost
) as Temp

Ответ 6

Я думаю, что следующее будет работать:

SELECT turnover, cost, turnover-cost as profit FROM
   (SELECT 1 AS FAKE_KEY, SUM(a_field) AS TURNOVER FROM some_table) a
INNER JOIN
   (SELECT 1 AS FAKE_KEY, SUM(a_nother_field) AS COST FROM some_other_table) b
USING (FAKE_KEY);

Не тестировался на животных - ты будешь первым!: -)

Поделитесь и наслаждайтесь.

Ответ 7

Вы можете использовать определенные пользователем переменные, такие как

SELECT
   @turnover := (SELECT SUM(...) FROM ...),
   @cost := (SELECT SUM(...) FROM ...),
   @turnover - @cost as profit

http://dev.mysql.com/doc/refman/5.7/en/user-variables.html

Ответ 8

Используйте крестик или внешний вид.

SELECT
  Calc1.turnover,
  Calc2.cost,
  Calc3.profit
from
   cross apply ((SELECT SUM(...) as turnover FROM ...)) as Calc1
   cross apply ((SELECT SUM(...) as cost FROM ...)) as Calc2

   /*
     Note there is no from Clause in Calc 3 below.
     This is how you can "stack" formulas like in excel.
     You can return any number of columns, not just one.
   */
   cross apply (select Calc1.turnover - Calc2.cost as profit) as Calc3

Ответ 9

Это довольно старый, но я столкнулся с этой проблемой и увидел этот пост, но мне не удалось решить мою проблему, используя приведенные ответы, поэтому я в конце концов пришел к этому решению:

если ваш запрос:

SELECT
   (SELECT SUM(...) FROM ...) as turnover,
   (SELECT SUM(...) FROM ...) as cost,
   turnover - cost as profit

вы можете включить его в подзапрос, а затем использовать такие поля, как:

SELECT *,(myFields.turnover-myFields.cost) as profit 
FROM
(      
SELECT
       (SELECT SUM(...) FROM ...) as turnover,
       (SELECT SUM(...) FROM ...) as cost

) as myFields

Я не совсем уверен, что это плохой способ делать что-то, но с точки зрения производительности, кажется, что мне кажется, что я запросил более 224,000 записей за 1,5 секунды не уверен, что позже он превратился в 2x одного и того же суб-запроса по базе данных.