さり海馬

Thoughts walk away, blog stays.

trac.db の中のテーブルを JOIN してみる

こんどは会社のSQLサーバーじゃなくて、trac の sqlite3 のデータの中身を解析することにしました。んでメモ。

trac.db の中にはいろいろテーブルが入っている*1けれども、実際にチケットに直接関係しているのは ticket と ticket_custom だけ。

ticketは id を主キーとして、type, component, summary, …というように、各属性が並んでいる*2 *3

id type ..... status summary description
1 仕様変更 ..... new ほげほげの仕様変更の件 このままだとダメになるぞ
2 仕様変更 ..... new ほげほげの仕様変更の件2 このままだとダメになるぞ2

ticket_custom はカスタム属性とその値のリストで、中身はこんな感じ

ticket name value
1 due_assign 2009/3/10
1 complete 2009/3/15
1 option D
2 due_assign 2009/3/22
2 complete 2009/3/28
2 option X

こいつらをjoinして普通にtracで見える形にするには、こういう感じでクエリ組むといいと思う

SELECT
  id
  ,type
  ,summary
  ,a.value AS 'DUE_ASSIGN'
  ,c.value AS 'COMPLETE'
  ,op.value AS 'OPTION'
FROM
  ticket t
    JOIN ticket_custom f ON f.ticket = t.id AND a.name = 'due_assign'
    JOIN ticket_custom b ON b.ticket = t.id AND c.name = 'complete'
    JOIN ticket_custom op ON op.ticket = t.id AND op.name = 'option'
WHERE
 t.type = '仕様変更'
 ORDER BY t.value
;

出てくる結果はこんな感じ

id type ..... status summary description DUE_ASSIGN COMPLETE OPTION
1 仕様変更 ..... new ほげほげの仕様変更の件 このままだとダメになるぞ 2009/3/10 2009/3/15 D
2 仕様変更 ..... new ほげほげの仕様変更の件2 このままだとダメになるぞ2 2009/3/22 2009/3/28 X

SQL初めてだったんですんげー悩みましたが、最終的にtracが吐き出すDEBUGログを眺めていて、同じテーブルを別のテーブルとして複数JOINしていいってことに気づいて解決しました。ログの中にはクエリがそのまま出力されてんのね。

*1:sqlite3 trac.db してから .tables すれば見られる

*2:ちなみにテーブルの中身をを確認するときは、.explain ON して、人間が理解しやすい出力にしとくと吉

*3:あと、確認するときは間違ってテーブルを破壊することのないように、trac.db をコピーして、コピーした方を使うことを強くお勧めしときます