Ответ 1
Так же:
SELECT
turnover,
cost,
turnover - cost as profit
from (
(SELECT SUM(...) FROM ...) as turnover,
(SELECT SUM(...) FROM ...) as cost
) as partial_sums
Пример:
SELECT
(SELECT SUM(...) FROM ...) as turnover,
(SELECT SUM(...) FROM ...) as cost,
turnover - cost as profit
Уверен, что это недопустимо (по крайней мере, в Postgres), но как добиться того же в запросе без повторной перезаписи суб-запроса?
Так же:
SELECT
turnover,
cost,
turnover - cost as profit
from (
(SELECT SUM(...) FROM ...) as turnover,
(SELECT SUM(...) FROM ...) as cost
) as partial_sums
Вы можете повторно использовать запрос следующим образом:
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
Здесь стоит отметить. Первый метод более читабельный и многоразовый, но второй метод может быть быстрее, потому что БД может выбрать лучший план для него.
Возможно, предложение sql "with" могло бы помочь, как представлено здесь http://orafaq.com/node/1879 (другие базы данных, такие как Postgres, также делают это, а не просто оракул).
Ура! Андре
На самом деле я много работал над этим и ударил по многим кирпичным стенам, но, наконец, понял ответ - больше взлома - но он работал очень хорошо и уменьшил накладные расходы на мои запросы на 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
Теперь у меня есть все три коррелированные "скалярные" значения, которые мне нужны, но мне нужно было выполнить только коррелированный подзапрос один раз вместо трех раз.
SELECT turnover, cost, turnover - cost
FROM
(
SELECT
(SELECT ...) as turnover,
(SELECT ...) as cost
) as Temp
Я думаю, что следующее будет работать:
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);
Не тестировался на животных - ты будешь первым!: -)
Поделитесь и наслаждайтесь.
Вы можете использовать определенные пользователем переменные, такие как
SELECT
@turnover := (SELECT SUM(...) FROM ...),
@cost := (SELECT SUM(...) FROM ...),
@turnover - @cost as profit
Используйте крестик или внешний вид.
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
Это довольно старый, но я столкнулся с этой проблемой и увидел этот пост, но мне не удалось решить мою проблему, используя приведенные ответы, поэтому я в конце концов пришел к этому решению:
если ваш запрос:
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 одного и того же суб-запроса по базе данных.