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

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

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

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

SQL

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

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

Q&A

解決済

3回答

4821閲覧

SQLで連結リストの探索のようなこと

hitsujimeeee

総合スコア486

MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

SQL

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

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

0グッド

0クリップ

投稿2016/12/03 10:42

編集2016/12/03 10:45

###前提・実現したいこと

DB上に以下のようなテーブルがあるとします。

IDWEIGHTNEXT_ID
1102
2203
3304
440NULL
5506
6603

IDは主キー、WEIGHTはその要素の重み、NEXT_IDはその要素の次の要素です。

この表に対して任意のIDを指定した時に、NEXT_IDをNULLになるまで順に辿り、その間に出現したWEIGHTの合計を求めたいです。
(例えばID=1とした場合10+20+30+40=100ID=6とした場合60+30+40=130が返却される)
※NEXT_IDがNULLにならずにいつまでもループする事は無いものとします。

###課題

現状、以下のようにPHP内で1行ずつセレクト文を発行しながら辿るような実装をしていますが、10レコード辿る場合は10回もSELECT文を発行しています。

PHP

1$id = 1; 2$sum = 0; //重みの合計 3while($id) { 4 $sql = 'SELECT WEIGHT, NEXT_ID FROM MY_TABLE WHERE ID = ' . $id; 5 6 //ここら辺でSQLを発行して$rowにレコードを格納 7 8 $sum += $row['WEGIHT']; 9 $id = $row['NEXT_ID']; 10}

SELECTの回数が多いのは何か気持ち感じがしてて、出来れば1回のSELECT文でNEXT_IDを最後まで辿って重みの合計を持ってくるようなクエリが理想なのですが、SQLのみでそれは可能でしょうか。

「SQLでそんなこと不可能だ」、「10回なんて細かい事気にせずクエリ投げまくれ」といった意見でも結構です。

よろしくお願いします。

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

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

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

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

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

guest

回答3

0

SQLが不得手なテーマではありますが、近年のRDBの多くが実装しているCTE(共通テーブル式)テーブル設計の工夫にて、
SQLのみでも解決できるテーマとなっています。

タイトルからは分かりにくいですが、
こちらRDBを用いた階層モデル・連結リストの実装手段について言及していますのでご参考までに。

また残念ながらMySQL、MariaDBでは未サポート(MariaDBではβ版でWITH句のサポートを始めるようなことは言ってた気がする・・・)となってますが、
tacsheavenさんが言及しているように、近年のRDBは再帰問い合わせの機能を標準で実装しています。
(WITH RECURSIVE句、RECURSIVE句は付けなくても良いかも?)

ご興味がありましたら、
調べてみると良いかもしれません。
(Oracle以外では、PostgreSQL、SQL Server、DB2もサポートしてますね)

投稿2016/12/03 15:05

Panzer_vor

総合スコア1636

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

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

hitsujimeeee

2016/12/03 16:03

MySQLでは再帰問い合わせはサポートしていないのですか、、、環境構築の手軽さからMySQLを使っているのですが、SQL Serverなどへの乗り換えも視野に入れてみようと思います。 色々とヒントを頂けたので自分で調べる足掛かりになりそうです。ありがとうございました。
guest

0

ベストアンサー

Oracle など階層問い合わせをサポートする RDBMS もあります。
再帰問い合わせによる方法、さらにはデータ構造を工夫することで実現する「入れ子構造モデル」と言った方法もあります。

いろいろ調べてみられるのがよろしいでしょう。

投稿2016/12/03 11:50

tacsheaven

総合スコア13703

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

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

hitsujimeeee

2016/12/03 15:59

再帰問い合わせという技術がある事を初めて知りました。少し調べてみてから手間や必要性を考えて導入するか考えてみようと思います。 回答していただきありがとうございました。
guest

0

テーブルの変更ができないなら、現状のままでいい気がします。
まあ、気分的にはアレでしょうが。

SQLの発行を減らしたいならストアドファンクションにする
って手もありますが、処理コストをどこで持つかの違いだけですね。

もし一意のIDから決まった数値を返すのが目的なら、
IDと合計WEIGHTを持つようにすれば簡単でしょうが…
たぶんそれはナシなんでしょうねえ。

投稿2016/12/03 12:38

takasima20

総合スコア7458

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問