2011-12-16 3 views
0

各行に式を適用し、最後にすべての結果を合計する必要がある行を合計する必要があります。私は合計の列に、前の式を具体化する必要はなく、列の名前を使用する必要があります。次のコードのようなものです(total_1、total_2、およびtotal_3は認識されないため機能しません)sqlの行と列の合計

SELECT 
    t.id, 
    t.dpt, 
    sum(t1.coefficient * t1.value) AS total_1, 
    sum(t2.coefficient * t2.value) AS total_2, 
    sum(t3.coefficient * t3.value) AS total_3, 
    (total_1 + total_2 + total_3) AS total -- Not recognized 
FROM my table t 
JOIN table1 t1 ON... 
JOIN table2 t2 ON... 
JOIN table3 t3 ON... 
group by t.id, t.dpt 

私はthefollowingような何かを行うことができます知っているが、それは和の定義で、いくつかの冗長性をemplies。

SELECT 
    t.id, 
    t.dpt, 
    sum(t1.coefficient * t1.value) AS total_1, 
    sum(t2.coefficient * t2.value) AS total_2, 
    sum(t3.coefficient * t3.value) AS total_3, 
    sum(t1.coefficient * t1.value + t2.coefficient * t2.value + t3.coefficient * t3.value) AS total 
FROM my table t 
JOIN table1 t1 ON... 
JOIN table2 t2 ON... 
JOIN table3 t3 ON... 
group by t.id, t.dpt 

列の合計を列の再定義を避けるために有効なクエリはありますか?私が考える

おかげ

答えて

2

最も簡単な方法は次のとおりです。

SELECT *, (total_1 + total_2 + total_3) AS total FROM (
    SELECT 
     t.id, 
     t.dpt, 
     sum(t1.coefficient * t1.value) AS total_1, 
     sum(t2.coefficient * t2.value) AS total_2, 
     sum(t3.coefficient * t3.value) AS total_3 
    FROM my table t 
    JOIN table1 t1 ON... 
    JOIN table2 t2 ON... 
    JOIN table3 t3 ON... 
    GROUP BY t.id, t.dpt 
) t 

追加

私は(私は彼らが異なることを知っていますが、テストする必要があり怒鳴るようなクエリをテストしてみましたあなた自身でそれを見分けるのが最良の方法です)。各実行の前に私はDBCC DROPCLEANBUFFERSDBCC FREEPROCCACHEを実行しました。 2回目の実行は数分後に実行され、その差はおそらくサーバの負荷によるものです。

SET STATISTICS TIME ON 

DBCC DROPCLEANBUFFERS 
DBCC FREEPROCCACHE 
go 

select t1.col1, sum(i.col2) as s, sum(i.col2) * 4 as smult 
from tab1 t1 
join tab2 t2 on t1.col1 = t2.col1 
group by t1.col1 

DBCC DROPCLEANBUFFERS 
DBCC FREEPROCCACHE 
go 

select *, s * 4 as smult from (
    select t1.col1, sum(i.col2) as s 
    from tab1 t1 
    join tab2 t2 on t1.col1 = t2.col1 
    group by t1.col1 
) t 

第一クエリの第一の実行:

SQL Server parse and compile time: 
    CPU time = 0 ms, elapsed time = 516 ms. 
SQL Server Execution Times: 
    CPU time = 63 ms, elapsed time = 3958 ms. 

第一クエリ第二の実行:

SQL Server parse and compile time: 
    CPU time = 0 ms, elapsed time = 374 ms. 
SQL Server Execution Times: 
    CPU time = 31 ms, elapsed time = 4152 ms. 

第二のクエリ第一ラン:

SQL Server parse and compile time: 
    CPU time = 0 ms, elapsed time = 513 ms. 
SQL Server Execution Times: 
    CPU time = 94 ms, elapsed time = 3445 ms. 

第二のクエリ第二の実行:

SQL Server parse and compile time: 
    CPU time = 16 ms, elapsed time = 363 ms. 
SQL Server Execution Times: 
    CPU time = 125 ms, elapsed time = 3146 ms. 
+0

私はそれも持っていましたが、2 SELECTを行うのがそれほど遅くないでしょうか?できるだけ早くselectを実行する必要があります。エラーを避けるために式を交換するのを避けたいのですが、性能を失うことなく – Javi

+0

@ Javiを編集してください。 –

+0

@MichałPowagaしたがって、2つの選択はより速くなります:) – Javi

0

(少なくともOracleで)最も効率的な方法は、ちょうどになります。

SELECT 
    t.id, 
    t.dpt, 
    sum(t1.coefficient * t1.value) AS total_1, 
    sum(t2.coefficient * t2.value) AS total_2, 
    sum(t3.coefficient * t3.value) AS total_3, 
    sum(t1.coefficient * t1.value) + sum(t2.coefficient * t2.value) + sum(t3.coefficient * t3.value) AS total 
FROM my table t 
JOIN table1 t1 ON... 
JOIN table2 t2 ON... 
JOIN table3 t3 ON... 
group by t.id, t.dpt 

Oracleは、それがすでに計算合計を持っているし、実行計画を変更しないことを認識するのに十分なスマートですので、ノーパフォーマンスペナルティ。

あなたは示唆した方法でそれを行うこともできます:合計(t1.coefficient * t1.value + t2.coefficient * t2.value + t3.coefficient * t3.value)。私の考えているパフォーマンスとまったく同じです。

あなたが話す冗長性は、スマートオプティマイザによって排除されます。