2016-03-24 11 views
3

私はTABLE_Aを持っており、それからTABLE_A_FINALを作成する必要があります。

ルール:
TABLE_A_FINALでは、可能なすべての組み合わせがID_Cであり、TABLE_Aの組み合わせがID_Cの場合は、WEIGHTの値を掛けます。
これはSQLで可能ですか?ヘルプとアドバイスをありがとう。SQL(乗算)のテーブル分析

TABLE_A
ID_N |WEIGHT |ID_C | 1 |1.15 | 1A | 2 |1.13 | 1A | 3 |1.65 | 1B | 4 |1.85 | 2A | 6 |1.57 | 2A |


TABLE_A_FINAL
ID_C |FINAL_WEIGHT | 1A |1.15×1.13 = 1.2995 | 1B |1.65 | 2A |1.85×1.57 = 2.9045 |

+1

(http://stackoverflow.com/a/21623421/593144): '(数値)AGGREGATE MULを作成する(SFUNC = numeric_mul、STYPE =数値); – Abelisto

答えて

3

残念ながら、Postgresはproduct()集計関数を持っていません。このような関数をsum()とログ/累乗でエミュレートすることができます。自分の価値観のすべてが正と非ゼロであるように見えるので:

select id_c, exp(sum(ln(weight)) as final_weight 
from table_a 
group by id_c; 

あなたがゼロまたは負の数を持っている場合、そのロジックではなく、より複雑な、まだ十分に可能です。連続したID_Cの連鎖を検出するためのウィンドウの上に

2

再帰CTE範囲:

WITH RECURSIVE yy AS (
     WITH xx AS (
       SELECT id_n,weight,id_c 
       , lead(id_n) over (PARTITION BY id_c ORDER BY id_n) AS nxt 
       , rank() over (PARTITION BY id_c ORDER BY id_n) rnk 
       FROM multipliers 
       ) 
     SELECT x0.rnk, x0.id_n,x0.weight,x0.id_c , x0.nxt 
       , x0.weight AS prod 
     FROM xx x0 
     WHERE x0.rnk = 1 -- START of a chain 
     UNION ALL 
     SELECT x1.rnk, x1.id_n,x1.weight,x1.id_c , x1.nxt 
       , yy.prod * x1.weight AS prod 
     FROM xx x1 
     JOIN yy ON x1.id_c = yy.id_c 
      AND x1.rnk = 1+ yy.rnk -- NEXT member of chain 
     ) 
SELECT * FROM yy 
WHERE yy.nxt IS NULL -- no next: this must be the END of a chain 
     ; 

ゼロまたは負の重みがある場合は、予想通り、これはまだ動作します。一部修正と[ここから】重量のNULL値yy.prod * AS COALESCE(x.weight,1) AS prodによって治療することができる、等

+0

助けてくれてありがとう:-) – hanznv

+0

@hanznv。 。 。私はあなたがこの答えを受け入れたことに驚いています。正しいものの、集約ソリューションよりもはるかに遅い可能性があります。 –

+0

@ GordonLinoff:数値的には正しいです。 exp/lnバージョンでは丸め誤差が発生する可能性があります。 – joop