また質問させて頂きます。宜しくお願いします。

現在添付画像のテーブルイメージのように情報を取得したいのですが、
方法が思い浮かず投稿させていただいています。

取得したい階層のイメージは、添付画像ツリーイメージのようになる事を求めています。

要望としては、
・PostgresSQL8.4で動作可能
・なるべくSQLで解決したい
・SQLのクエリ発行数に関してはなるべく1回が良いですが別に2回以上でも使用可
(ただし、アプリケーション側でループ処理とかは無し。1000回ループとかありえるんで。。。)
・必要ならば一時テーブルの作成もあり


お手数ですが、どなたか方法・アドバイス等お教え頂ければ助かります。

「SQLで階層(ツリー)情報を取得」の質問画像

このQ&Aに関連する最新のQ&A

A 回答 (1件)

PostgreSQLの環境がないので試すことができないのですが、


connectby()関数を使ってみてはどうでしょうか。
「PostgreSQL 階層問合せ」などで検索してみるといいと思います。
参考になれば幸いです。

この回答への補足

せっかくご回答して頂いたのに、お礼が遅くなって大変申し訳ございません。
上記回答して頂いた内容を調べてみました。

現在Ver8.4では「WITH RECURSIVE」という処理でわかりやすい文法になってるようですね。
こういう処理自体はじめて知りました。

尚、現状ですがツリーイメージにあります、リーフ(末端)からルート(最上位)までの階層を取得する処理は以下のSQL文で解決しましたが、全てのリーフ(末端)を取得するようなSQLはできませんでした。(もう少しでできそうだったんですが…)

ループで回すしか無いですかね…


--現状のSQL------------------------------------------------------
WITH RECURSIVE rec(階層ID, 階層名, 親階層ID, 末端階層ID) as (

SELECT
階層ID,
階層名,
親階層ID,
'03' AS 末端階層ID ← '03'は末端階層ID(とりあえず末端の'03'を使用)
FROM
階層管理テーブル
WHERE
階層ID = '03'

UNION ALL

SELECT
A.階層ID,
A.階層名,
A.親階層ID,
'03' AS 末端階層ID ← '03'は末端階層ID(とりあえず末端の'03'を使用)

FROM 階層管理テーブル A

INNER JOIN rec
ON A.階層ID = rec.親階層ID

)
SELECT * FROM rec
ORDER BY 親階層ID,
階層ID

-------------------------------------------------------------------

補足日時:2011/05/09 00:24
    • good
    • 0

このQ&Aに関連する人気のQ&A

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

関連するカテゴリからQ&Aを探す

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

QPostgresSQL8.4でツリー上に取得したい

PostgresSQL8.4でツリー上に取得したい
こんにちわ。
PostgresSQLでツリー上にデータを取得したいのですが、思ったように取得できないのでご教授をお願いします画像の「取得したい順番」。
データはid,name,parentとの構造になっています。
データは親子構造になっており、親の下に子が並ぶようにしたいんです。
子は親のidをparentに持っています。
元のデータは画像の「元データ」になっています。
現状再起SQLでデータを取得しid or parentでソートを掛けているのですが、意図した通りに取得できません画像の「取得出来る順番」。
そもそも再起SQLでできるのか、相関サブクエリを使うのか・・・SQLのみでできるのかすら分からなくなってきました・・・。
何か画像の「取得したい順番」通りに取得する方法はないでしょうか。
ヒントだけでもいいので、ご教授をお願いします。

Aベストアンサー

#1 です。

余計なお世話かもしれませんが、親子関係で階層的にデータを持たせるのは、主たる要素の意味合いの粒度が同じ場合の方が好ましいです。

例えば、前便のサンプルで頻出する社員テーブルの場合、主キーは社員ID、エンティティの意味する粒度は親でも子でも変わらない「社員」です。

ご質問の場合、アジア→日本→東京(地域→国名→地名)のように粒度が荒いので、マスタとして今後、使いにくくなっていく可能性があります。

既に設計済みでもう変えられないなら、仕方ありませんが。

また、単純に地名マスタ程度の意味合いしかないのであれば、今のままでも問題無いと思います。

Q階層問い合わせ?親子展開したVIEWを作りたい

親子のデータを展開したVIEWを作成したいのですが、調べてみると
階層問い合わせというものがあるということまで分かりました。
(階層問い合わせ自体よく分かっていません)

その内容でSQLを以下のように記述してみたのですが、どうも思惑と
若干違います。思惑は親コードは最上位のものを出して、そこに子供で
ぶらさがっているKOCDを全部羅列したいのです。

どのようなSQLにすれば可能でしょうか。ご教授のほど、お願い致します。

記述したSQL
SELECT OYACD,KOCD
FROM TBL1
START WITH OYACD = 0
CONNECT BY PRIOR KOCD = OYACD

TBL1の内容
OYACD KOCD
--------------
1000110002
1000110003
1000120001
2000120002
2000120003
010001 親=0が最上位の親

SQLの結果
OYACD KOCD
--------------
010001  
1000110002
1000110003
1000120001
2000120002  ここと
2000120003  ここのOYACD 現在はひとつ上の親が出ている

このSQLの結果のOYACDで20001が最上位のOYACDの10001として
見えるようなSQLにしたいのですが、どうすれば可能でしょうか。

このように見えて欲しい
OYACD KOCD
--------------
010001  
1000110002
1000110003
1000120001
1000120002  ここと
1000120003  ここを最上位の親を表示したい。

親子のデータを展開したVIEWを作成したいのですが、調べてみると
階層問い合わせというものがあるということまで分かりました。
(階層問い合わせ自体よく分かっていません)

その内容でSQLを以下のように記述してみたのですが、どうも思惑と
若干違います。思惑は親コードは最上位のものを出して、そこに子供で
ぶらさがっているKOCDを全部羅列したいのです。

どのようなSQLにすれば可能でしょうか。ご教授のほど、お願い致します。

記述したSQL
SELECT OYACD,KOCD
FROM TBL1
START WITH OYACD = 0
CONNECT B...続きを読む

Aベストアンサー

connect_by_root演算子で最上位の値を取得できます。

SELECT
CASE WHEN LEVEL = 1 THEN OYACD ELSE CONNECT_BY_ROOT KOCD END OYACD
,KOCD
FROM TBL1
START WITH OYACD = 0
CONNECT BY PRIOR KOCD = OYACD;
としてみてください。

最上位の場合はOYACDをそのまま出力するようにするために、LEVELを使って判断しています。

すでに読んでいらっしゃるかもしれませんが、こちらが分かりやすく解説してくれていると思います。
http://codezine.jp/article/corner/301

Q3つの表の外部結合

表A、B、Cの3つがあり、Aのすべての行を出力したいと考えています。
外部結合を用いるのだとは思うのですが、3つの表に対して行う場合の
書き方がわからず困っています。
ご教授いただけないでしょうか?
select * from a,b,c
where a.商品ID =b.商品ID (+) and b.商品ID (+) =c.商品ID (+)
としてみましたが、うまくいきませんでした。

Aベストアンサー

ansi構文の趣旨からいえば、結合条件と絞り込み条件は分けて書くので・・

select *
from a
left join b on (a.商品ID =b.商品ID)
left join c on (b.商品ID =c.商品ID)
where a.年月 = 任意の値

と書くのが一般的でしょうね。

Q文字列として"(ダブルコーテーション)を表示させる方法

こんにちは。文字列として、ダブルコーテーションを表示させるには、どうすればよいのか教えてください。m(__)m


例えば、
<font size="2">あいうえお</font>

というタグの「あいうえお」の部分が、セルA1にあった場合、

="<font size="2">"&A1&"</font>"という表示にしたいのです。

"2"のダブルコーテーションも文字列として表示させるには、どうすればよろしいのでしょうか。

教えてください。よろしくお願い致します。

Aベストアンサー

こんにちは~

表示形式は 「標準」 のままで、
ダブルコーテーションを、ダブルコーテーションで囲んでください。

""2""

="<font size=""2"">"&A1&"</font>"

としてみてください。

Qツリー情報のデータをSQLで取得したい

SQLServer 2008 です。

以下のツリーデータの場合に

A ┬C
│├D ┬H
││ ├I
││ └J
│└E
B ┬F ┬I
 │ └L
 └G

次のようなデータを登録しています。
┌──┬──┬──┐
│OYA │KO │Data│
├──┼──┼──┤
│A │C  │"C" │
├──┼──┼──┤
│A  │D  │"D" │
├──┼──┼──┤
│A  │E  │"E" │
├──┼──┼──┤
│B  │F  │"F" │
├──┼──┼──┤
│B  │G  │"G" │
├──┼──┼──┤
│D  │H  │"H" │
├──┼──┼──┤
│D  │I  │"I" │
├──┼──┼──┤
│D  │J  │"J" │
├──┼──┼──┤
│F  │I  │"I" │
├──┼──┼──┤
│F  │L  │"L" │
└──┴──┴──┘

引数OYA="A"でSQLを実行した場合に
以下のような
この引数を含むそれ以下のツリーに関する
データを取得する方法を教えてください。

┌──┬──┬──┐
│OYA │KO │Data│
├──┼──┼──┤
│A │C  │"C" │
├──┼──┼──┤
│A  │D  │"D" │
├──┼──┼──┤
│A  │E  │"E" │
├──┼──┼──┤
│D  │H  │"H" │
├──┼──┼──┤
│D  │I  │"I" │
├──┼──┼──┤
│D  │J  │"J" │
└──┴──┴──┘

SQLServer 2008 です。

以下のツリーデータの場合に

A ┬C
│├D ┬H
││ ├I
││ └J
│└E
B ┬F ┬I
 │ └L
 └G

次のようなデータを登録しています。
┌──┬──┬──┐
│OYA │KO │Data│
├──┼──┼──┤
│A │C  │"C" │
├──┼──┼──┤
│A  │D  │"D" │
├──┼──┼──┤
│A  │E  │"E" │
├──┼──┼──┤
│B  │F  │"F" │
├──┼──┼──┤
│B  │G  │"G" │
├──┼──┼──┤
│D  │H  │"H" │
├──┼──┼──┤
│D  │I  │"I" │
├──┼──┼──┤
│D  │J  │"J" │
├──┼──┼──┤
│F  │I  │"I" │
├──┼──┼──┤
│F  │L  │"L" │
└──┴──┴──┘

引数OYA="A"でSQL...続きを読む

Aベストアンサー

再帰SQL(クエリ)の出番だと思いますが、持ち合わせていないので
リンクだけです。ご勘弁。
http://www.atmarkit.co.jp/fnetwork/tokusyuu/01sql99/sql99_1b.html

Qファイルに記述されている複数のSQL文を一度に実行させたい

こんにちわ。

ファイルに記述されているSQL文を、Linuxのコマンドラインなどから
実行したいと考えています。

ファイルに
insert into DB_NAME(aaa,bbb,ccc) values(111,222,333);
insert into DB_NAME(ddd,eee,fff) values(333,777,222);
insert into DB_NAME(aaa,ttt,ddd) values(111,000,999);
...

などのSQL文が複数行(例えば1000個ほど)記述しているのを用意して
なんかしらの方法で一度に実行させたいのです。

mySQLでは、このようなやり方があるのですが
postgreではどのようにすればいいのか、わかりません。

どなたかご存知の方、よろしくお願い致します。

OSはLinuxです。

Aベストアンサー

#1の方も指摘されている通り、 psql を使えば出来ます。

psql で、-f オプションを使うか、該当のDBに接続して \i コマンドを使えば良いでしょう。
http://www.postgresql.jp/document/pg746doc/html/app-psql.html

SQLが記述されているファイルを insert_data.sql、
DBを testdb としますと
例1)-------------------------------------------------------------
$ psql testdb
Welcome to psql x.x.x, the PostgreSQL interactive terminal.




testdb=> \i insert_data.sql
testdb=> \q
-----------------------------------------------------------------

例2)-------------------------------------------------------------
$ psql testdb -f insert_data.sql
-----------------------------------------------------------------

注) ユーザのDBへのアクセス権によっては -U オプションや -W オプションも必要になります。

#1の方も指摘されている通り、 psql を使えば出来ます。

psql で、-f オプションを使うか、該当のDBに接続して \i コマンドを使えば良いでしょう。
http://www.postgresql.jp/document/pg746doc/html/app-psql.html

SQLが記述されているファイルを insert_data.sql、
DBを testdb としますと
例1)-------------------------------------------------------------
$ psql testdb
Welcome to psql x.x.x, the PostgreSQL interactive terminal.




testdb=> \i insert_data.sql
testdb=> \q...続きを読む

QonClickに複数の関数を挿入する方法

初心者なのですがアニメーションの関数anime1、anime2、anime3を作成し、onClickに下記のように設定しました。
クリックするとアニメーション2つの設定ではは動くのですが、3つ目を設定すると動かなくなります。
通常はこのような設定はしないものなのでしょうか?
教えてください。
よろしくお願いします。
<INPUT type="button" value="START" onClick="anime1(), anime2()">・・・OKです。
<INPUT type="button" value="START" onClick="anime1(), anime2(),anime3()">・・・動きません。

Aベストアンサー

セミコロンでつなぐのが常道ですが、3つ以上なら
別途function化したほうが、可読性が高くなると
思います。

Q複数行の結果を単一列に連結

以下のような【TABLE1】と【TABLE2】をID_SUBの列で結合した結果を
【A.結果】のように取得したいのですがうまくいきません。

【TABLE1】
ID ID_SUB
1 A1
2 B1

【TABLE2】
ID ID_SUB ID_SUB_CODE
1 A1 AAA1
2 A1 AAA2
3 B1 BBB1
4 B1 BBB2

【A.結果】
ID_SUB ID_SUB_CODE
A1 "AAA1,AAA2"
B1 "BBB1,BBB2"

いろいろ調べたのですが、MySQLにはGROUP_CONCATの
関数を使うと簡単に出来るみたいですが、PostgreSQLには
似たような関数がなく、ARRAYが使えるかな?と思ってためしてみましたが

array_to_string(ARRAY(ID_SUB_CODE, ','))

等のような感じで試した結果、ID_SUB_CODEが
全て連結されるような使い方しか出来ませんでした。

A1 "AAA1,AAA2,BBB1,BBB2"
B1 "AAA1,AAA2,BBB1,BBB2"

何か良い方法はありますでしょうか?

以下のような【TABLE1】と【TABLE2】をID_SUBの列で結合した結果を
【A.結果】のように取得したいのですがうまくいきません。

【TABLE1】
ID ID_SUB
1 A1
2 B1

【TABLE2】
ID ID_SUB ID_SUB_CODE
1 A1 AAA1
2 A1 AAA2
3 B1 BBB1
4 B1 BBB2

【A.結果】
ID_SUB ID_SUB_CODE
A1 "AAA1,AAA2"
B1 "BBB1,BBB2"

いろいろ調べたのですが、MySQLにはGROUP_CONCATの
関数を使うと簡単に出来るみたいですが、PostgreSQLには
似たような関数がなく、ARRAYが使え...続きを読む

Aベストアンサー

select id_sub,
( select array_to_string(ARRAY(select id_sub_code from table2
where table1.id_sub=table2.id_sub ), ',') )
from table1;

なんて参考になりませんか。

Qsqlに記述できない文字

いつもお世話になっております。
WEB画面から入力された項目を対象にPostgresに検索しに行っているのですが、シングルクォート(')が入っていた場合、エラーになってしまいました。

JavaからSQLを生成し、Postgresに接続しているのですが、シングルクォートを検索させるにはどうするのが良いでしょうか。

またSQLに記述できない文字は、シングルクォートのほかに何かありますでしょうか。

よろしくお願いします。

Aベストアンサー

下記のページにPostgreSQLのSQLの文字列定数についての説明が有りますので、記述できない文字などについてはここを見ると良いでしょう。
http://www.postgresql.jp/document/pg837doc/html/sql-syntax-lexical.html#SQL-SYNTAX-STRINGS

さて、シングルクウォートを含む文字列定数への対応としては下記の3つが考えられます。
1. 文字列中のシングルクウォートとバックスラッシュ(\)を\でエスケープする。
2. ドル引用符を使用する。
3. プレースフォルダを使用する。


2は、$xxxx$ のようなドル記号で囲まれた文字列を引用符代わりに使う、PostgreSQL 独自の機能です。
'hoge' と書く代わりに $xxxx$hoge$xxxx$ の様に書けます。
詳しくは下記のページを見て下さい。
http://www.postgresql.jp/document/pg837doc/html/sql-syntax-lexical.html#SQL-SYNTAX-DOLLAR-QUOTING

3は、SQLの定数の位置に?を書き、PreparedStatement の set~~() メソッドを使って値を指定する方法です。下記のページが参考になるでしょう。
http://www.atmarkit.co.jp/fjava/rensai2/webopt11/webopt11.html
http://sdc.sun.co.jp/java/docs/j2se/1.4/ja/docs/ja/guide/jdbc/getstart/preparedstatement.html

参考URL:http://www.postgresql.jp/document/pg837doc/html/sql-syntax-lexical.html#SQL-SYNTAX-CONSTANTS

下記のページにPostgreSQLのSQLの文字列定数についての説明が有りますので、記述できない文字などについてはここを見ると良いでしょう。
http://www.postgresql.jp/document/pg837doc/html/sql-syntax-lexical.html#SQL-SYNTAX-STRINGS

さて、シングルクウォートを含む文字列定数への対応としては下記の3つが考えられます。
1. 文字列中のシングルクウォートとバックスラッシュ(\)を\でエスケープする。
2. ドル引用符を使用する。
3. プレースフォルダを使用する。


2は、$xxxx$ のようなドル記号で囲...続きを読む

Q配列に指定した値が含まれているものを抽出する方法

こんにちは。
いつもお世話になっております。

SQLにて、配列のフィールドに指定した値が含まれているものを抽出する方法を質問致します。


SQLのテーブル(テーブル名:data)に配列のフィールド(フィールド名:array[])があるとします。
Array[]フィールドの中に、1, 2, 6のいずれかが含まれている場合表示対象となるSQL文を書くには、どのように書けばよいですか。PostgreでSQL文を書くとします。


実現したい動作は以下の通りです。
array[] の値
{1,3,5} 表示対象になる
{3,8,9,10}  表示対象にならない
{2,6} 表示対象になる

以上よろしくお願い致します。


ちなみに、array[]フィールドの中に、2(指定した数値が1つだけ)を探すとき、
select * from data where 2=any (array);
とすればいいことは確認できました。

Aベストアンサー

&& 演算子 (重複する, 共通要素を持つ) を使います。

SELECT * FROM (VALUES
(ARRAY[1,3,5]),
(ARRAY[3,8,9,10]),
(ARRAY[2,6])
) T(arr)
WHERE ARRAY[1,2,6] && arr;

参考URL:http://www.postgresql.jp/document/current/html/functions-array.html


人気Q&Aランキング