MW211 EXIT

devlog
PostgreSQL/更新順は指定できませんよ
2013年04月24日
挿入時には挿入順(並び順)を指定できる。
┌──────────────────────────────────────┐
│INSERT INTO 出力表 (列) SELECT 列 FROM 入力表 ORDER BY 列 ASC;              │
└──────────────────────────────────────┘

更新時には更新順(並び順)を指定できない。以下は(「ORDER BY」以降)無理。
┌──────────────────────────────────────┐
│UPDATE 出力表 SET 列 = 入力表.列 FROM 入力表 ORDER BY 入力表.列 ASC;        │
└──────────────────────────────────────┘

解決策としてはSQL関数を使うってのがある。
┌──────────────────────────────────────┐
│仮入力表 RECORD;                                       DECLARE領域で変数定義│
├──────────────────────────────────────┤
│FOR 仮入力表 IN SELECT 列 FROM 入力表 ORDER BY 列 ASC LOOP                  │
│    UPDATE 出力表                                                           │
│        SET 列 = 仮入力表.列                                                │
│        WHERE 列 = 仮入力表.列;                                             │
│END LOOP;                                                                   │
└──────────────────────────────────────┘

ま、たいていは影響のない話だろう。タイムスタンプをつけても同一になるだけだし。
これが問題となったのは、「UPDATE」にトリガを仕込んで
変更履歴を「INSERT」させた時。
変更履歴が意図した順で追加されなかったのだ。
分類:PostgreSQL
PostgreSQL/最大値を更新(2)
2013年04月22日
もうちょっと簡単な方法。
これだと、更新するレコードのみを更新できる。
┌──────────────────────────────────────┐
│UPDATE 更新表                                                               │
│  SET 最大 = 入力表.値                                                      │
│  FROM 入力表                                                               │
│  WHERE 入力表.キー = 更新表.キー                                           │
│    AND (入力表.値 > 更新表.最大                                            │
│      OR 更新表.最大 IS NULL)                                               │
└──────────────────────────────────────┘
ちなみに「SET 最大 =」のところを「SET 更新表.最大 =」としてはいけないみたい。

それと、これはPostgreSQL独自の仕様の模様。
分類:PostgreSQL
PostgreSQL/時刻型→数値型
2013年02月25日
to_char()で文字型にしてから、to_number()で数値型にする。
直接ってのはないようだ
┌──────────────────────────────────────┐
│SELECT to_number(to_char(now(),'YYYY'),'9999');                         →年│
│SELECT to_number(to_char(now(),'MM'),'9999');                           →月│
│SELECT to_number(to_char(now(),'DD'),'9999');                           →日│
│SELECT to_number(to_char(now(),'HH24'),'99');                           →時│
│SELECT to_number(to_char(now(),'MI'),'99');                             →分│
│SELECT to_number(to_char(now(),'SS'),'99');                             →秒│
└──────────────────────────────────────┘

…と思ったら、あった。直接ってのが。「extract()」を使う。
┌──────────────────────────────────────┐
│SELECT extract(YEAR FROM now());                                        →年│
│SELECT extract(MONTH FROM now());                                       →月│
│SELECT extract(DAY FROM now());                                         →日│
│SELECT extract(HOUR FROM now());                                        →時│
│SELECT extract(MINUTE FROM now());                                      →分│
│SELECT trunc(extract(SECOND FROM now()));                               →秒│
└──────────────────────────────────────┘
秒に関しては端数(ミリ秒)も付随してしまうので
「trunc()」で切り捨ててしまった方がいいかも。
分類:PostgreSQL
PostgreSQL/条件分岐UPDATE文
2013年02月20日
条件によりUPDATEしたい値を変えたい場合には、CASE文が使える。
┌──────────────────────────────────────┐
│UPDATE 表                                                                   │
│    SET 列 = (CASE                                                          │
│                WHEN 条件 THEN 値                                           │
│                ELSE           値                                           │
│              END);                                                         │
└──────────────────────────────────────┘
CASE文の前後を囲む括弧はなくてもよいみたい。
分類:PostgreSQL
PostgreSQL/ランダムな並び替え
2013年02月19日
「ORDER BY」句に「random()」を使う。

こんな感じ。
┌──────────────────────────────────────┐
│SELECT 列 FROM 表 ORDER BY random();                                        │
└──────────────────────────────────────┘
分類:PostgreSQL
PostgreSQL/乱数に重みをつける
2013年02月18日
ただランダムに値を取得するのではなく、頻度を分けたい場合がある。
「1」の目を多く出るようにしたい場合とかである(コンプガチャか!?)

こういう場合は、配列と組み合わせてこんな感じにできるであろう。
┌──────────────────────────────────────┐
│SELECT (ARRAY[1,1,2,3,4,5,6])[trunc(random() * 7) + 1];               →1~6│
└──────────────────────────────────────┘
これだと、「1」(はずれ?)の目の確率が他の二倍となる。
分類:PostgreSQL
PostgreSQL/乱数
2013年02月17日
乱数は「random()」で「0以上1未満」の値が取得できる。

「trunc()」(切り捨て)と組み合わせると、「0から指定した値未満まで」を取得できる。
┌──────────────────────────────────────┐
│SELECT trunc(random() * 10);                                          →0~9│
└──────────────────────────────────────┘
分類:PostgreSQL
PostgreSQL/剰余計算
2013年02月15日
「mod()」を使う。
「mod(割られる数,割る数)」の書式だ。

試しにいろいろな数を「3」で割ってみると。
┌──────────────────────────────────────┐
│SELECT mod(-4,3);                                                       →-1│
│SELECT mod(-3,3);                                                       → 0│
│SELECT mod(-2,3);                                                       →-2│
│SELECT mod(-1,3);                                                       →-1│
│SELECT mod( 0,3);                                                       → 0│
│SELECT mod( 1,3);                                                       → 1│
│SELECT mod( 2,3);                                                       → 2│
│SELECT mod( 3,3);                                                       → 0│
│SELECT mod( 4,3);                                                       → 1│
└──────────────────────────────────────┘
分類:PostgreSQL
PostgreSQL/ANALYZEとは(2)
2013年02月14日
で、実際の「ANALYZE」の実行について。

┌──────────────────────────────────────┐
│ANALYZE;                                                                    │
└──────────────────────────────────────┘
単なる「ANALYZE」は、全ての表を対象とする。

┌──────────────────────────────────────┐
│ANALYZE 表;                                                                 │
└──────────────────────────────────────┘
もちろん表を絞り込むことができる。

┌──────────────────────────────────────┐
│ANALYZE VERBOSE;                                                            │
└──────────────────────────────────────┘
「VERBOSE」を付けると進行状況を報告してくれる。
分類:PostgreSQL
PostgreSQL/ANALYZEとは(1)
2013年02月13日
「ANALYZE」は「統計情報」を最新に更新してくれる機能。

SQLでデータを読み込む時に、いろいろな方法がある。
目的地にたどり着くのにいろいろな経路があるようなものだ。

意識しなくても、一番最適な(最速な)経路をみつけてくれる(実行計画という)のだが、
その判断根拠となるのが、「統計情報」になる。

インプット情報が正しくなければ正しい結果は導き出せないので、
「統計情報」ってのはかなり大事だといえよう。

たいていは、「VACUUM」同様、都度、統計情報は最新に更新されるモードがとられるが、
任意で実行したい場合には「ANALYZE」を使う。

┌──────────────────────────────────────┐
│EXPLAIN SQL文;                                                              │
└──────────────────────────────────────┘
SQL文の先頭に「EXPLAIN」を付けて実行すると、実行計画が提示される。
┌──────────────────────────────────────┐
│… (cost=… rows=1234 …)                                                   │
└──────────────────────────────────────┘

さらに「EXPLAIN ANALYZE」にすると、実行計画の提示とともに
実際に実行してその見積もり(実行計画)がどうだったか教えてくれる。
┌──────────────────────────────────────┐
│EXPLAIN ANALYZE SQL文;                                                      │
└──────────────────────────────────────┘
こんな感じの結果となる。
┌──────────────────────────────────────┐
│… (cost=… rows=1234 …) (actual … rows=123456 …)                        │
└──────────────────────────────────────┘
「actual」(実際に)の後が、実際の結果だ。
見積もりでは「1234」だったのに、実際にやってみたら「123456」だった…って
見積もり大間違いじゃんというオチである。

ま、そんな時に「ANALYZE」を実行して、「統計情報」を最新にってことだ。

ちなみに、「ANALYZE」は全件調査するわけではなく、無作為抽出調査だ。
そのサンプル数を増やせば改善される場合もある。
分類:PostgreSQL
前へ 1 2 3 4 5 6 7 8 9 10 11 次へ