Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

generate_series関数使い込み

1,519 views

Published on

PostgreSQLアンカンファレンス@東京(9/6)での発表資料です

Published in: Technology
  • Be the first to comment

  • Be the first to like this

generate_series関数使い込み

  1. 1. generate_series関数使い込み PostgreSQLアンカンファレンス@東京(9/6) 河原翔 1
  2. 2. generate_series関数とは • 集合を返す関数 2 SELECT * FROM generate_series(2,4); generate_series ----------------- 2 3 4 SELECT * FROM generate_series('2008-03-01 00:00'::timestamp, '2008-03-04 12:00', '10 hours'); generate_series --------------------- 2008-03-01 00:00:00 2008-03-01 10:00:00 2008-03-01 20:00:00 2008-03-02 06:00:00 :
  3. 3. 一般的?な用途 • 試験用データの作成 • 存在しない値を集計結果に表示する • 行列変換 3 PostgreSQLでテストデータを作成する— Let's Postgres http://lets.postgresql.jp/documents/technical/gen_data/1 Postgres generate_series関数によるデータの生成| Fusic Developers Weblog http://blog.fusic.co.jp/archives/810 列を行に変換する- PostgreSQL 雑記- postgresqlグループ http://postgresql.g.hatena.ne.jp/pgsql/20110414 行を列に変換する- PostgreSQL 雑記- postgresqlグループ http://postgresql.g.hatena.ne.jp/pgsql/20110416
  4. 4. 前方最長完全一致検索 • 条件 ・検索文字列「ABCDE」を対象列から検索する ・前方から最も完全一致している文字数が多い行を取得する ・ただし、検索文字列に含まれていない文字が含まれる行は つまり・・・ 4 取得対象外とする A ← 一致 BC ← 不一致(Aから始まっていない) ABC ← 一致 ABCD ← 一致(最長) ABCDEF← 不一致 (Fが検索文字列に含まれていないため不一致)
  5. 5. 前方最長完全一致検索 • クエリ例 5 SELECT * FROM test; col1 -------- A BC ABC ABCD ABCDEF SELECT * FROM test WHERE col1 IN (SELECT left('ABCDE',generate_series(1,length('ABCDE')))) ORDER BY length(col1) DESC LIMIT 1; col1 ------ ABCD left ------- A AB ABC ABCD ABCDE 最長の完全一致を取得
  6. 6. 文字列のソート • order byでの列ソートではなく文字列毎のソート • つまり 「PQODJHAZBDVACWKABOWPX」を 「AAABBCDDHJKOOPPQVWWXZ」とする 6
  7. 7. 文字列のソート • 途中クエリ1 7 SELECT col1 FROM (SELECT generate_series(1,3) col1) foo; col1 ------ 1 2 3 配列を文字列に変換複数行を配列に変換 SELECT array_to_string(array_agg(col1),'') FROM (SELECT generate_series(1,3) col1) foo; array_to_string ----------------- 123 複数行を集約できる
  8. 8. 文字列のソート • 途中クエリ2 8 SELECT * FROM test; col1 ------ SQL DATA SELECT col1,substr(col1,generate_series(1,length(col1)),1) sub FROM test ORDER BY col1,sub; col1 | sub ------+----- DATA | A DATA | A DATA | D DATA | T SQL | L SQL | Q SQL | S 1文字ずつ分解してsort
  9. 9. 文字列のソート • クエリ例 9 SELECT * FROM test; col1 ----------------------- PQODJHAZBDVACWKABOWPX UDFPGIEHAPTNVUDIIEHAO SELECT col1,array_to_string(array_agg(sub),'') sorted FROM (SELECT col1,substr(col1, generate_series(1,length(col1)),1) sub FROM test ORDER BY col1,sub) foo GROUP BY col1; col1 | sorted -----------------------+----------------------- PQODJHAZBDVACWKABOWPX | AAABBCDDHJKOOPPQVWWXZ UDFPGIEHAPTNVUDIIEHAO | AADDEEFGHHIIINOPPTUUV
  10. 10. 欠番探し • クエリ例 10 SELECT id FROM test; id --------- ID00005 ID00006 ID00008 ID00009 ID00010 SELECT id FROM (SELECT 'ID' || lpad(generate_series(1,10)::text,5,'0') id) foo WHERE id NOT IN (SELECT id FROM test); id --------- ID00001 ID00002 ID00003 ID00004 ID00007 id --------- ID00001 ID00002 ID00003 ID00004 ID00005 ID00006 ID00007 ID00008 ID00009 ID00010 文字列連結、lpad、 castを併用

×