例:
SELECT
(SELECT SUM(...) FROM ...) as turnover,
(SELECT SUM(...) FROM ...) as cost,
turnover - cost as profit
確かにこれは(少なくともPostgresでは)無効ですが、サブクエリを2回書き換えずにクエリで同じことを達成する方法は?
そのようです:
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
ここで注意すべき点があります。最初の方法は読みやすく再利用可能ですが、2番目の方法はDBがより適切な計画を選択する可能性があるため、より高速になる可能性があります。
おそらく、ここに示されているように、sqlの「with」句が役立つ場合があります http://orafaq.com/node/1879 (Oracleだけでなく、Postgresなどの他のデータベースも同様に行います)。
実際に私はこれについて多くの作業を行い、多くのレンガの壁にぶつかりましたが、最終的に答えを見つけました-より多くのハック-しかし、それは非常にうまく機能し、クエリの読み取りオーバーヘッドを90%削減しました...
したがって、相関クエリを何度も複製してサブクエリから複数の列を取得するのではなく、コンマで区切られた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
これで、必要な3つの相関「スカラー」値がすべて揃いましたが、相関サブクエリは3回ではなく1回実行するだけで済みました。
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
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
レコードは、DBによる同じサブクエリの2倍になっているかどうかが不明で、1.5秒かかりました。