2017-03-23 13 views
1

SASコード(PROC SQL)を(postgres)SQLに変換する必要があります。特に、クエリで定義された変数を同じクエリで直接再利用できるようにするSASのcalculatedキーワード別の変数の計算のために:1つのテーブルスキャンで複数の列演算をグループ化する

SELECT 
    id, 
    sum(case 
     when (sales > 0) then 1 
     when (sales = 0) then 0 
     else -1 
    end) as pre_freq, 
    (case 
     when calculated pre_freq > 0 then calculated pre_freq 
     else 1 
    end) as freq 
FROM my_table 
GROUP BY id 

これは、SQLで(私の知る限り)ことはできませんので、私は計算の各ステップを打破する必要があります。

私が理解しているように、小さなテーブルスキャンではなく、複数のテーブルスキャンの代わりに、より多くの計算と少ないテーブルスキャン、つまりスキャン中の計算を行う方がよいということを知っていました。計算ステップ。

SELECT 
     id 
    , greatest(1, sum(case 
     when (sales > 0) then 1 
     when (sales = 0) then 0 
     else -1 
    end) as freq 
FROM 
    my_table 
GROUP BY id 

か::私は使用することができ、この特定のexempleで

SELECT 
     id 
     , (case when sum(case 
       when (sales > 0) then 1 
       when (sales < 0) then -1 
       else 0 
     end) > 0 then sum(case 
       when (sales > 0) then 1 
       when (sales < 0) then -1 
       else 0 
     end) else 1 end) as freq 
FROM 
    my_table 
GROUP BY id 

...読みにくくなり始めている...

  • がありますとにかく繰り返されるSQLコードのスニペットの変数を定義するには?
  • もっと一般的に言えば、このイラストレーションは最高の(最も効率的な)アプローチでしたか?
+0

これらの1、-1、0のフラグを表す新しい列を追加してから、合計してください。 – Veljko89

+0

どちらの代替も 'id'でグループ化する必要があります。私はSASについて知らない。それはあなたが欲しいものですか? 'freq'を' id'で実行しますか? –

+0

@ClodoaldoNeto確かにsasとsqlの両方のためです。編集されました。 – ant1j

答えて

2

calculatedは、proc sqlという素晴らしい機能です。しかし、一般的なデータベースでエイリアスを再利用することはできません(これはPostgres固有の制限ではありません)。

select id, pre_freq, 
     (case when pre_freq > 0 then pre_freq 
      else 1 
     end) as freq 
from (select id, 
      sum(case when (sales > 0) then 1 
         when (sales = 0) then 0 
         else -1 
       end) as pre_freq, 
     from my_table t 
     group by id 
    ) t; 

しかし、最も簡単な解決策は、sign()を使用することである:

select id, sum(sign(sales)) as pre_freq, 
     greatest(sum(sign(sales)), 1) as freq 
from my_table t 
group by id; 

注:これはわずかに異なっている簡単な方法は、サブクエリまたはCTEを使用することです。基本的にはNULLの値は無視されます。 NULLを-1として扱う必要がある場合は、coalesce()を使用してください。

+0

私はあなたが 'least'(?)ではなく' greatest'を意味すると思います。そして、あなたはCTE(2つのテーブルのスキャンを含む)が1つの単純なスキャン(この例では)よりも処理に時間がかかることを私は理解するでしょうか? – ant1j

+0

@ ant1j特定のCTEは、特定のサブクエリと意味的に同等ですが、プランナは前者に対しては最適化できません。 –

+0

@ ant1j。 。 。ありがとうございました。 –

関連する問題