質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.46%
PostgreSQL

PostgreSQLはオープンソースのオブジェクトリレーショナルデータベース管理システムです。 Oracle Databaseで使われるPL/SQLを参考に実装されたビルトイン言語で、Windows、 Mac、Linux、UNIX、MSなどいくつものプラットフォームに対応しています。

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

Q&A

解決済

2回答

1873閲覧

階層を持ったテーブルで、子要素が存在するか判定したい

chained_method

総合スコア6

PostgreSQL

PostgreSQLはオープンソースのオブジェクトリレーショナルデータベース管理システムです。 Oracle Databaseで使われるPL/SQLを参考に実装されたビルトイン言語で、Windows、 Mac、Linux、UNIX、MSなどいくつものプラットフォームに対応しています。

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

0グッド

0クリップ

投稿2020/02/17 09:50

編集2020/02/17 10:28

使用しているDBは、Postgresql バージョン12です。

レコードに親子関係を持たせて、子が存在するかどうかを判定したいのですが、正常に判定出来ません。
親子関係の条件は、
レコード(仮にA)の[親ID]列の値が他のレコード(仮にB)の[ID]列の値と一致し、Aの階層がBの階層+1になっていれば、
AをBの子とみなし、Bの[子あり]をtrueとする。
という条件です。

ID親ID階層
10null1
11102
12102
13null1

現在、動かないクエリ

SELECT id, 親id, 階層, (SELECT count(t1.id) > 0 FROM myTable t1 INNER JOIN myTable t2 ON t1.id = t2.親id WHERE t1.id = t2.親id AND (t1.階層 = (t2.階層 - 1)) as 子あり FROM myTable;

欲しい結果

ID親ID階層子あり
10null1true
11102false
12102false
13null1false

現在の結果
どうやっても全レコードが一括でtrueかfalseになってしまいます。

ID親ID階層子あり
10null1true
11102true
12102true
13null1true

欲しい結果を得るにはどうすればよいでしょうか?

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Orlofsky

2020/02/17 10:24

同じSQLでもデータベースやそのバージョンによって方言が大きいですから、どのデータベースを使うのかを質問のタグで示したり、バージョンも明記した方が適切なコメントが付き易いです。
chained_method

2020/02/17 10:29

ありがとうございます。本文の先頭にバージョンを明記し、タグを追加致しました。
Orlofsky

2020/02/17 10:41

質問にCREATE TABLEやデータのINSERTも提示できた方が良いです。
guest

回答2

0

親子関係(2階層)しかないのであれば以下で。

SQL

1SELECT 2 id, 親id, 階層 3, exists(SELEC 1 from myTable where 親ID=t1.ID and 階層=t1.階層+1) as 子あり 4FROM 5 myTable t1

投稿2020/02/17 11:46

編集2020/02/17 11:53
sazi

総合スコア25206

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

sazi

2020/02/17 11:58

上記は相関副問合せによるものです。 階層+1のような演算は主側(この場合はt1)側に行うように気を付けて下さい。 そうしないと、比較項目にインデックスがあっても効率が悪いですから。
chained_method

2020/02/17 12:03

ありがとうございます。 2階層限定のテーブルも多数使用する事になる為、その際はこちらを使用させて頂きます。
sazi

2020/02/17 13:04 編集

階層数が限定でない場合は、再帰呼び出しを使用する事になります。 注意点は、ベストアンサーも同じ相関副問合せなので同じですよ。
guest

0

ベストアンサー

冗長的ですが

sql

1select t1.id, t1.親id, t1.階層, 2case when exists(select 1 from myTable t2 where t1.ID=t2.親ID and t1.階層+1=t2.階層) 3then true else false end "子あり" 4from myTable t1;

投稿2020/02/17 11:35

amura

総合スコア333

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

chained_method

2020/02/17 11:56

目から鱗が落ちた思いです。 本当にありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.46%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問