13

私はPostgreSQL9.1.2を使用しており、以下のような基本的なテーブルがあります。ここには、ブール値としてのエントリのサバイバルステータスと (Survival)日数があり(Survival(Days))ます。

名前の付いた新しい列を手動で追加しました1-yr Survival。次に、テーブルの各エントリについて、そのエントリSurvivalSurvival (Days)列の値を条件として、この列の値を入力します。完了すると、データベーステーブルは次のようになります。

Survival    Survival(Days)    1-yr Survival
----------  --------------    -------------
Dead            200                NO
Alive            -                 YES
Dead            1200               YES

の条件付き値を入力するための擬似コードは、次の1-yr Survivalようになります。

ALTER TABLE mytable ADD COLUMN "1-yr Survival" text
for each row
if ("Survival" = Dead & "Survival(Days)" < 365) then Update "1-yr Survival" = NO
else Update "1-yr Survival" = YES
end 

これは基本的な操作だと思いますが、実行するためのpostgresql構文が見つかりませんでした。一部の検索結果には「トリガーの追加」が返されますが、それが必要かどうかはわかりません。ここでの私の状況はもっと単純だと思います。任意のヘルプ/アドバイスをいただければ幸いです。

4

2 に答える 2

12

ワンタイム操作はプレーンで実現できますUPDATE

UPDATE tbl
SET    one_year_survival = (survival OR survival_days >= 365);

名前にキャメルケース、空白、括弧を使用しないことをお勧めします。二重引用符で囲むことは許可されていますが、多くの場合、複雑化や混乱を招きます。マニュアルの識別子とキーワードに関する章を検討してください。

クエリの結果をCSVとしてエクスポートできることをご存知COPYですか?
例:

COPY (SELECT *, (survival OR survival_days >= 365) AS one_year_survival FROM tbl)
TO '/path/to/file.csv';

そもそも、この方法で冗長な列は必要ありません。


コメントへの追加の回答

空の更新を回避するには:

UPDATE tbl
SET    "Dead after 1-yr" = (dead AND my_survival_col < 365)
      ,"Dead after 2-yrs" = (dead AND my_survival_col < 730)
....
WHERE  "Dead after 1-yr" IS DISTINCT FROM (dead AND my_survival_col < 365)
   OR  "Dead after 2-yrs" IS DISTINCT FROM (dead AND my_survival_col < 730)
...

個人的には、やむを得ない理由がある場合にのみ、このような冗長な列を追加します。通常はしません。パフォーマンスに関する場合:式のインデックスと部分インデックスを知っていますか?

于 2012-08-29T19:10:13.247 に答える
6

正直なところ、保存されたデータからすばやく簡単に計算されるデータベースにデータを保存しない方がよいと思います。より良いオプションは、計算されたフィールドをシミュレートすることです(ただし、以下に注意する点)。この場合、メンテナンスを容易にするために、スペースなどをアンダースコアに変更します。

CREATE FUNCTION one_yr_survival(mytable)
RETURNS BOOL
IMMUTABLE
LANGUAGE SQL AS $$
select $1.survival OR $1.survival_days >= 365;
$$;

次に、実際に次のことができます。

SELECT *, m.one_year_survival from mytable m;

そしてそれは「うまくいく」でしょう。次の落とし穴に注意してください。

  • mytable.1_year_survivalは、デフォルトの列リストでは返されません。
  • パーサーがこれをone_year_survival(m)に変換するため、テーブル識別子(上記の例ではm)を省略できません。

ただし、利点は、値が他の値と同期しなくなることがないことを証明できることです。そうしないと、チェック制約のネズミの巣になってしまいます。

あなたは実際にこのアプローチをかなり遠くまで取ることができます。http://ledgersmbdev.blogspot.com/2012/08/postgresql-or-modelling-part-2-intro-to.htmlを参照してください

于 2012-08-30T00:49:36.297 に答える