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

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

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

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

SQL

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

WordPress

WordPressは、PHPで開発されているオープンソースのブログソフトウェアです。データベース管理システムにはMySQLを用いています。フリーのブログソフトウェアの中では最も人気が高く、PHPとHTMLを使って簡単にテンプレートをカスタマイズすることができます。

PHP

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

Q&A

解決済

2回答

1159閲覧

SQLで取得した特定スレッドごとのコメント群について、カラムを順繰りにUPDATEしたい

ikatako

総合スコア270

MySQL

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

SQL

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

WordPress

WordPressは、PHPで開発されているオープンソースのブログソフトウェアです。データベース管理システムにはMySQLを用いています。フリーのブログソフトウェアの中では最も人気が高く、PHPとHTMLを使って簡単にテンプレートをカスタマイズすることができます。

PHP

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

1グッド

1クリップ

投稿2020/11/01 12:36

###前提
以下3つのテーブル構成です。
・スレッドp_threads
・コメントp_comments
・それらのスーパータイプp_matters

###現状と目的
p_commentsorder_numberというカラムが現状では0ですが、これを同一スレッドごとに順繰りにUPDATEしたいと思っています。

現状はこうで↓、order_number0ですが、
イメージ説明

目的はこうで↓、order_numberが同一スレッドごと(thread_IDごと)に更新された状態です。
イメージ説明

###ソースコード
上の現状を示すテーブルになります。

-- 投稿 (スーパータイプ) CREATE TABLE p_matters (`ID` int, `kind` int, `sentence` varchar(1000), `created_at` DATETIME(6)) ; INSERT INTO p_matters (`ID`, `kind`, `sentence`, `created_at`) VALUES # thread は kind=1 で comment は kind=2 (1, 1, '猫について語りましょう', '2020-01-01 12:00:00.123456'), (2, 1, '犬について語りましょう', '2020-01-02 12:00:00.123456'), (3, 2, '猫はいいです', '2020-01-03 12:00:00.123456'), (4, 2, 'たしかに猫は最高です', '2020-01-04 12:00:00.123456'), (5, 1, '鰐について語りましょう', '2020-01-05 12:00:00.123456'), (6, 2, '鰐は怖いです', '2020-01-06 12:00:00.123456'), (7, 2, '犬はやわらかいです', '2020-01-07 12:00:00.123456'), (8, 2, '猫は液体です', '2020-01-08 12:00:00.123456'), (9, 2, '猫は液体ではないです', '2020-01-09 12:00:00.123456'), (10, 2, '鰐は怖くないです', '2020-01-10 12:00:00.123456') ; -- 投稿 (サブタイプ/スレッド) CREATE TABLE p_threads (`matter_ID` int, `title` varchar(100)) ; INSERT INTO p_threads (`matter_ID`, `title`) VALUES (1, '猫スレ'), (2, '犬スレ'), (5, '鰐スレ') ; -- 投稿 (サブタイプ/コメント) CREATE TABLE p_comments (`matter_ID` int, `thread_ID` varchar(10), `order_number` int) ; INSERT INTO p_comments (`matter_ID`, `thread_ID`, `order_number`) VALUES (3, 1, 0),(4, 1, 0),(6, 5, 0),(7, 2, 0),(8, 1, 0),(9, 1, 0),(10, 5, 0) ;

###試したこと
SQLだけでできれば楽ですが、自分にできることと合わせて、

  1. SQLで取得
  2. PHPで編集
  3. SQLで更新

という流れで以下試してみました。

ですが同一スレッドであるにも拘わらず、同じorder_numberが保存されてしまっています。
var_dump($comments);でスレッドごとにわかれていることを確認しているのに、なぜこのようなことになるのか理解できません。

保存処理はできているので$iがおかしいのだと思いますが、何がいけないのでしょうか。

php

1// すべてのコメントを取得 2$sql = " 3SELECT * 4FROM p_matters matters 5LEFT JOIN p_comments comments ON comments.matter_ID=matters.ID 6WHERE matters.kind=2 AND matters.ID IS NOT NULL 7ORDER BY matters.created_at ASC 8"; 9$rows = $wpdb->get_results( $sql, ARRAY_A ); 10var_dump($rows); 11 12// created_at でソート 13foreach ( $rows as $key => $value ) { 14 $created_at[$key] = $value['created_at']; 15} 16array_multisort( $created_at, SORT_ASC, $rows ); 17var_dump($rows); 18 19// 同一スレッドごとに整理 20$comments = []; 21foreach ( $rows as $row ) { 22 $thread_ID = $row['thread_ID']; 23 $comments[$thread_ID][] = $row; 24} 25var_dump($comments); 26 27// コメントテーブルに order_number を入れていく 28foreach ( $comments as $thread_ID => $rows ) { 29 if( empty($thread_ID) ) continue; 30 31 $i = 1; 32 foreach ( $rows as $row ) { 33 $target = [ 'matter_ID' => $row['ID'] ]; 34 $update = [ 'order_number' => $i ]; 35 $row = $wpdb->update( 'p_comments', $update, $target, ['%d'], ['%d'] ); 36 $i++; 37 } 38} 39
yodel👍を押しています

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

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

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

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

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

guest

回答2

0

ベストアンサー

SQL

1update p_comments as t2,(select matter_ID,(select count(*)+1 from p_comments where thread_ID=t1.thread_ID and matter_ID<t1.matter_ID) as order_number 2from p_comments as t1) as t3 3set t2.order_number=t3.order_number 4where t2.matter_ID=t3.matter_ID

投稿2020/11/02 02:14

yambejp

総合スコア114983

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

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

ikatako

2020/11/02 09:48

1回のクエリで済むとは、すごいです。処理がめちゃくちゃ早くなりました。が > 同一スレッドであるにも拘わらず、同じorder_numberが保存されてしまっています。 という問題は解消されません。 しかしこの重複問題、どうやらこちらの質問のコードやご回答のコードなど「更新過程」に原因があるのではなく、phpMyAdminでの「表示過程」の方に問題があるのかもしれません。 その点は別途質問(https://teratail.com/notifications/30/301719)で投稿中なので(あちらへもご回答ありがとうございます)、ひとまずこちらの質問はこれで閉じさせて頂きます。ありがとうございました。
guest

0

php

1$target = [ 'matter_ID' => $row['ID'] ]; 23$target = [ 'ID' => $row['ID'] ];

ではないですか?

投稿2020/11/02 02:13

KazuhiroHatano

総合スコア7804

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

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

ikatako

2020/11/02 09:49

CREATEした際にIDというカラムは設けませんでしたので、その部分はmattar_IDでよさそうです。アドバイスありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.46%

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

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

質問する

関連した質問