MW211 EXIT

devlog
PostgreSQL/INSERT件数
2012年11月03日
「INSERT INTO 出力先 SELECT 入力元」みたいな、INSERT文を実行した場合、
実際に何件挿入されたか気になるところ。

実行直前と直後にそれぞれ「SELECT COUNT(*)」で件数を取得して差分をとるという
地道な方法以外に件数を簡単に取得する方法はないものか

PL/pgSQLだったら、以下で挿入件数を取得できる。
┌──────────────────────────────────────┐
│GET DIAGNOSTICS 変数(INTEGER型) = ROW_COUNT;                                │
└──────────────────────────────────────┘
分類:PostgreSQL
PostgreSQL/文字列をtimestamp型に変換する方法
2012年11月02日
┌──────────────────────────────────────┐
│SELECT TO_TIMESTAMP('2013-01-30 16:13:18','YYYY-MM-DD HH24:MI:SS');         │
└──────────────────────────────────────┘
みたいな感じ。

第二引数のYとかMとかは「書式テンプレートパターン」ってやつを参照のこと。

たいていは、その前にtimestamp型を文字列に変換していたりするので、
その逆をやればいいということになる。
┌──────────────────────────────────────┐
│SELECT TO_CHAR(NOW(),'YYYY-MM-DD HH24:MI:SS');                              │
└──────────────────────────────────────┘
分類:PostgreSQL
PostgreSQL/並び順の更新
2012年10月10日
対象列を基準として並び順を更新したい場合のSQL文。
┌──────────────────────────────────────┐
│UPDATE 表                                                                   │
│    SET 並び順 = (SELECT COUNT(*)                                           │
│                      FROM 表 AS t1,                                        │
│                           表 AS t2                                         │
│                      WHERE 表.主キー  = t1.主キー                          │
│                        AND t1.対象列 >= t2.対象列                          │
│                      GROUP BY t1.対象列)                                   │
└──────────────────────────────────────┘
分類:PostgreSQL
PostgreSQL/表から該当項目数を求める
2012年10月07日
┌──────────────────────────────────────┐
│┌────┬────┬────┬────┬────┐                        │
││  キー  │  枝番  │小条件1 │小条件2 │小条件3 │                        │
│├────┼────┼────┼────┼────┤┐                      │
││   A   │    1   │   ○   │        │        ││                      │
│├────┼────┼────┼────┼────┤│                      │
││   A   │    2   │        │        │   ○   ││                      │
│├────┼────┼────┼────┼────┤│グループ              │
││   A   │    3   │   ○   │   ○   │        ││                      │
│├────┼────┼────┼────┼────┤│                      │
││   A   │    4   │        │        │   ○   ││                      │
│├────┼────┼────┼────┼────┤┘                      │
││   B   │    1   │        │   ○   │        │                        │
│└────┴────┴────┴────┴────┘                        │
│                    └──────────────┘                        │
│                               フィールド                                   │
└──────────────────────────────────────┘
上記のようなテーブルから、グループ毎に○の数を求めるSQL文。(Aなら5つ)

┌──────────────────────────────────────┐
│SELECT キー,                                                                │
│         SUM(CASE WHEN 小条件1 = TRUE THEN 1 ELSE 0 END)                    │
│       + SUM(CASE WHEN 小条件2 = TRUE THEN 1 ELSE 0 END)                    │
│       + SUM(CASE WHEN 小条件3 = TRUE THEN 1 ELSE 0 END) AS 件数            │
│    FROM 表                                                                 │
│    WHERE 大条件 = TRUE                                                     │
│    GROUP BY キー;                                                          │
└──────────────────────────────────────┘
SUM()の中で、CASE文を使えば簡単にできる(文自体は長文になるけど)。
分類:PostgreSQL
PostgreSQL/結果に連番をふる
2012年10月01日
SQL出力結果に連番をふるには以下の通り。
┌──────────────────────────────────────┐
│SELECT ROW_NUMBER() OVER() FROM 表;                                         │
└──────────────────────────────────────┘

連番の順番を指定するには以下のようにOVER()内にORDER BY句をつければよい。
┌──────────────────────────────────────┐
│SELECT ROW_NUMBER() OVER(ORDER BY 列 ASC) FROM 表;                          │
└──────────────────────────────────────┘
いくつかのSQL文を複合する場合、途中の並び替えは無視されるから、
これをつかって並び順を記憶させたりできるのかも。

ちなみにグループ化してその中での枝番的な連番をふる方法は以下の通り。
┌──────────────────────────────────────┐
│SELECT ROW_NUMBER() OVER(PARTITION BY 列) FROM 表                           │
└──────────────────────────────────────┘
PARTITION BYの後にグループ化のキーとなる列を指定すればよい。
分類:PostgreSQL
PostgreSQL/列幅縮小
2012年09月17日
例えば16バイトの文字列を8バイトとする場合は、以下のような感じ。
┌──────────────────────────────────────┐
│UPDATE 表                                                                   │
│    SET 列 = SUBSTR(列, 1, 8);                                              │
├──────────────────────────────────────┤
│ALTER TABLE 表                                                              │
│    ALTER COLUMN 列                                                         │
│    TYPE character varying(8);                                              │
└──────────────────────────────────────┘
UPDATE文で事前にデータを切り捨てておけばスムーズに移行できる。

もちろん、サイズを大きく変更すれば列幅拡大ができる。
この場合は、当然ながら切り捨ては不要だ。
分類:PostgreSQL
PostgreSQL/日付を変更して更新
2012年09月05日
「年月日」の文字列、例えば「20120801」とかを一日前に置換するUPDATE文。
┌──────────────────────────────────────┐
│UPDATE 表                                                                   │
│    SET 日付 = TO_CHAR(TO_DATE(日付, 'YYYYMMDD') - 1, 'YYYYMMDD');          │
└──────────────────────────────────────┘
「20120731」になる。
分類:PostgreSQL
PostgreSQL/条件でログを削除する
2012年09月02日
年月日時分秒ごとにデータを記録しているログデータについて、
翌日になったらクリアしてから追加していくトリガ関数は以下のような感じ
┌──────────────────────────────────────┐
│DECLARE                                                                     │
│    pl_yyyymmdd CHAR(8);                                                    │
│                                                                            │
│BEGIN                                                                       │
│    SELECT INTO pl_yyyymmdd                                                 │
│                SUBSTR("yyyymmddhhiiss", 1, 8) AS "yyyymmdd"                │
│        FROM 表;                                                            │
│                                                                            │
│    IF TG_OP = 'INSERT' THEN                                                │
│        IF SUBSTR(NEW.yyyymmddhhiiss, 1, 8) <> pl_yyyymmdd THEN             │
│            DELETE FROM 表;                                                 │
│                                                                            │
│            RETURN NEW;                                                     │
│        END IF;                                                             │
│    END IF;                                                                 │
│                                                                            │
│    RETURN NEW;                                                             │
│END;                                                                        │
└──────────────────────────────────────┘
こいつをトリガとして登録すればOK。
┌──────────────────────────────────────┐
│CREATE TRIGGER トリガ                                                       │
│  BEFORE INSERT                                                             │
│  ON 表                                                                     │
│  FOR EACH ROW                                                              │
│  EXECUTE PROCEDURE トリガ関数();                                           │
└──────────────────────────────────────┘
これってINSERTの度に判断するんだろうけど、負荷がかかるのだろうか?

DELETEに代えてTRUNCATE TABLEにしようとしたら、エラーとなった。
┌──────────────────────────────────────┐
│DECLARE                                                                     │
│    pl_yyyymmdd CHAR(8);                                                    │
│                                                                            │
│BEGIN                                                                       │
│    SELECT INTO pl_yyyymmdd                                                 │
│                SUBSTR("yyyymmddhhiiss", 1, 8) AS "yyyymmdd"                │
│        FROM 表;                                                            │
│                                                                            │
│    IF TG_OP = 'INSERT' THEN                                                │
│        IF SUBSTR(NEW.yyyymmddhhiiss, 1, 8) <> pl_yyyymmdd THEN             │
│            TRUNCATE TABLE 表;                                              │
│                                                                            │
│            RETURN NEW;                                                     │
│        END IF;                                                             │
│    END IF;                                                                 │
│                                                                            │
│    RETURN NEW;                                                             │
│END;                                                                        │
└──────────────────────────────────────┘
これからINSERTしようとする表をDDLのレベルでは操作できないようだ。
ま、全件削除ってより、1ヶ月過ぎたのを削除とかが普通かも。
分類:PostgreSQL
PostgreSQL/バージョンをSQL文で
2012年08月22日
PostgreSQLのバージョンをSQL文で知るためには?
┌──────────────────────────────────────┐
│SELECT version();                                                           │
└──────────────────────────────────────┘
「PostgreSQL 9.1.3, compiled by Visual C++ build 1500, 64-bit」みたいな結果が
得られる。

これから正規表現を使って、先頭だけ抜き出すと…。
┌──────────────────────────────────────┐
│SELECT SUBSTRING(VERSION() FROM '^PostgreSQL \d(?:.\d+)*');                 │
└──────────────────────────────────────┘
「PostgreSQL 9.1.3」が抽出できる。

さらには括弧で囲うと…。
┌──────────────────────────────────────┐
│SELECT SUBSTRING(VERSION() FROM '^PostgreSQL (\d(?:.\d+)*)');               │
└──────────────────────────────────────┘
「9.1.3」のみが抽出できる。
分類:PostgreSQL
PostgreSQL/最小値と最大値
2012年08月20日
定数とか充実してりゃいいんだけど・・・。
┌─────┬───┬────────────────────────────┐
│smallint  │最小値│-32768                                                  │
│          │最大値│+32767                                                  │
├─────┼───┼────────────────────────────┤
│integer   │最小値│-2147483648                                             │
│          │最大値│+2147483647                                             │
├─────┼───┼────────────────────────────┤
│bigint    │最小値│-9223372036854775808                                    │
│          │最大値│9223372036854775807                                     │
├─────┼───┼────────────────────────────┤
│serial    │最小値│1                                                       │
│          │最大値│2147483647                                              │
├─────┼───┼────────────────────────────┤
│bigserial │最小値│1                                                       │
│          │最大値│9223372036854775807                                     │
├─────┼───┼────────────────────────────┤
│money     │最小値│-21474836.48                                            │
│          │最大値│+21474836.47                                            │
├─────┼───┼────────────────────────────┤
│date      │最小値│'epoch'::date                                           │
├─────┼───┼────────────────────────────┤
│timestamp │最小超│'-infinity'::timestamp                                  │
│          │最小値│'epoch'::timestamp                1970-01-01 00:00:00+00│
│          │最大超│'infinity'::timestamp                                   │
└─────┴───┴────────────────────────────┘
分類:PostgreSQL
前へ 1 2 3 4 5 6 7 8 9 10 11 次へ