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

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

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

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

PDO

PDO(PHP Data Objects)はPHPのデータベース抽象化レイヤーです。

WordPress

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

PHP

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

Q&A

解決済

1回答

3849閲覧

特定もカラムの最大値を有するレコードを取得する

SugiuraY

総合スコア317

MySQL

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

PDO

PDO(PHP Data Objects)はPHPのデータベース抽象化レイヤーです。

WordPress

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

PHP

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

0グッド

0クリップ

投稿2016/10/15 07:01

編集2016/10/15 09:37

お世話になります。
現在、以下のテーブルの状況です。

Atable secid sales 100 200 100 500 200 50 200 100 300 1000

ここでsecidカラムの中で100のgroupに属する最大のsalesのレコードを取得したいです。(つまりsecid:100,
1 sales:500のレコードです)
これについて

$secid=100; $sql1 = $wpdb->prepare("SELECT * FROM $wpdb->Atable WHERE secid=%d AND sales=(SELECT MAX(sales) from Atable)",$secid); *wordpressの$wpdbクラスを利用していてますが、通常のSQL文やPDOの記法でのご回答でも構いません。 通常のPDOであれば以下のようになりますでしょうか。 $sql1 = prepare("SELECT * FROM Atable WHERE secid=:secid AND sales=(SELECT MAX(sales) from Atable)); stmt->bindValue(':secid',$secid,PDO::PARAM_STR); https://wpdocs.osdn.jp/%E9%96%A2%E6%95%B0%E3%83%AA%E3%83%95%E3%82%A1%E3%83%AC%E3%83%B3%E3%82%B9/wpdb_Class
var_dumpの結果 array (size=0) empty

where句でsecidとmax条件を絞るような方法はダメなのでしょうか?
いろいろ調べたのですが、うまくいかなかったため、ご質問させていただきました。

よろしくお願い申し上げます。


以下、追加の状況
A.ichi様にご教示頂いた方法で、データを取得することができたのですが、幾つかのカラムについて
想定していないデータを持ってきてしまいます。
実際のコードとテーブルの方がご理解いただきやすいと思いましたので
いかに記載します。

quote.phpで取得した配列の結果の結果をごらんください
'xki' => string '28' (length=2)
'fisperiod' => string '2015年6月期' (length=14)

について、table $wpdb->zaimumasterの配列(テーブル)にある通り
本来はMAX値の201606のレコードであれば
'xki' => string '30' (length=2)
'fisperiod' => string '2016年6月期' (length=14)
を持ってこなければならないのに、intperiodが
201512のMIN値のものを持ってきます。
重ねてで申し訳ございませんが、よろしくお願い申し上げます。

quote.php $sql1 = $wpdb->prepare("SELECT*FROM $wpdb->zaimumaster t1 JOIN (SELECT secid,xki,fisperiod,max(intperiod) intperiod FROM $wpdb->zaimumaster GROUP BY secid) t2 using(secid,intperiod) where t1.secid=%d",$secid); $rows1 = $wpdb->get_results(($sql1), ARRAY_A); var_dump($rows1);
quote.phpで取得した配列の結果 array (size=1) 0 => array (size=25) 'secid' => string 'ZZZZ' (length=4) 'intperiod' => string '201606' (length=6) 'id' => string '3' (length=1) 'name' => null 'xki' => string '28' (length=2) 'period' => string '前期' (length=6) 'fisperiod' => string '2015年6月期' (length=14) ```ここに言語を入力 table $wpdb->zaimumaster array (size=3) 0 => array (size=25) 'id' => string '1' (length=1) 'name' => null 'xki' => string '28' (length=2) 'secid' => string 'ZZZZ' (length=4) 'period' => string '3期前' (length=7) 'fisperiod' => string '2015年6月期' (length=14) 'intperiod' => string '201506' (length=6) 1 => array (size=25) 'id' => string '2' (length=1) 'name' => null 'xki' => string '29' (length=2) 'secid' => string 'ZZZZ' (length=4) 'period' => string '2期前' (length=7) 'fisperiod' => string '2015年12月期' (length=15) 'intperiod' => string '201512' (length=6) 2 => array (size=25) 'id' => string '3' (length=1) 'name' => null 'xki' => string '30' (length=2) 'secid' => string 'ZZZZ' (length=4) 'period' => string '前期' (length=6) 'fisperiod' => string '2016年6月期' (length=14) 'intperiod' => string '201606' (length=6)

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

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

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

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

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

timy

2016/10/15 08:11

例だと最大salesは500なのでは? intperiod というカラムは何? 「ダメなのでしょうか?」とありますが上記のコードを実行した結果はどうなっていますか?
SugiuraY

2016/10/15 08:18

timyさま コメントありがとうございます。ご指摘の通り修正いたしました。SQLからはエラーが吐き出されず、var_dumpの結果は空です。。その旨も加筆いたしました。
A.Ichi

2016/10/15 10:07

余分と思われる部分を削除いたしました。
guest

回答1

0

ベストアンサー

sqlの部分だけです、ご参考まで

sql

1$secid=100; 2$stmt = $wpdb->prepare("select t1.* from Atable t1 join (select secid, max(sales) sales from Atable group by secid) t2 using(secid,sales) where t1.secid=:secid"); 3$stmt->bindValue(':secid',$secid)); 4$status = $stmt->execute(); 5if (!$status) { 6 $err = $stmt->errorInfo(); 7} 8$rec=$stmt->fetch(PDO::FETCH_ASSOC); 9print_r ($rec);

上記の例題を見て修正してみました

sql

1$sql1 = $wpdb->prepare(" 2SELECT * FROM $wpdb->zaimumaster t4 JOIN 3(SELECT id,xki,secid FROM $wpdb->zaimumaster t1 4 JOIN (SELECT secid, max(intperiod) intperiod FROM $wpdb->zaimumaster) t2 5 USING( secid,intperiod ) WHERE secid=%d 6) t3 USING (id,xki,secid); 7",$secid);

投稿2016/10/15 08:33

編集2016/10/15 11:34
A.Ichi

総合スコア4070

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

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

SugiuraY

2016/10/15 08:57

ご回答いただき、ありがとうございます。 今、ご教示いただいた内容で、エラーが出ているので、細かいコードを見直しているのですが、先に確認させていただきたいのですが、 SELECT secid, Max(sales) FROM Atable GROUP BY secid のようなSQL文を書くとsalesだけ最大値を取得し、配列の他の要素は全く違うレコードから値を取得してきます。単純に同じsecidのグループないで最大値を持つレコードのすべての情報を持ってきたいだけなのですが、、以外と複雑で驚いています。 このあたりの仕様がまだわからないのですが、ご指摘いただいたjoinやサブクエリといった考え方と関連があるのでしょうか? よろしくお願い申し上げます。
SugiuraY

2016/10/15 09:38

ご教示頂いた方法で、データは取得できたのですが、一部違うレコードのデータを取得してきます。上記の質問に改めて加筆させていただきました。 度々で恐れいりますが、よろしくお願い申し上げます。
A.Ichi

2016/10/15 10:10

他の部分が見えていませんでした、修正しましたが、余分な部分が無くなりましたでしょうか?
SugiuraY

2016/10/15 10:15

申し訳ないございません、余分な部分とはご提示頂いたコードの中の余分な部分でしょうか? もしそうであれば、コードを戻して差分をみてみます。
SugiuraY

2016/10/15 10:25

特に差分はないようです。よろしくお願い申し上げます。
A.Ichi

2016/10/15 10:32

select * を select t1.* としました。join にて余分な項目出ていると思いましたので。
A.Ichi

2016/10/15 10:35

もしかしてsecid,salesにてユニークにならないと言う事ですか?
SugiuraY

2016/10/15 10:45

お世話になります。 修正後のコードで無事必要な情報を取得することができました、誠にありがとうございます、まだSQL文に慣れていないため、細かい勉強はこれから実施するのですが、xkiやfisperiodが違うレコードから値を取得してきた原因はどのようなものになるのでしょうか?ちょっと、このコードでt1.*で取得する値はすべてjoin以下で得られるカラムの情報ですと明示的に示さなければならない?ということでしょうか。 度々、恐れ入りますがよろしくお願い申し上げます。
SugiuraY

2016/10/15 10:55

すみません、当初のシンプルな例はご放念ください。 後から提示させていただいたコードで申し上げると secid->secid sales->intperiod になります。 この点、両者を組み合わせた場合は一意になります。 よろしくお願い申し上げます。
SugiuraY

2016/10/15 11:17

度々失礼致します。やはり調べていても頭が混乱してきたので、最後に噛み砕いておうかがいさせていただければと存じます。重ねての質問、確認失礼致します。 なお、下記のコードは修正後の(シンプルではないバージョンで成功したコードで書き換えています。) 1.SELECT t1. *FROM $wpdb->zaimumaster >>$wpdb->zaimumasterテーブルのすべて(*)のレコードの値を取得するということかと思いますがt1. の意味がやはりわかりません。これは$wpdb->zaimumasterテーブルそのものをt1と明示的にしており、そのテーブルのすべて(*)を取得したいよということでしょうか? 2.JOIN (SELECT secid,max(intperiod) intperiod FROM $wpdb->zaimumaster GROUP BY secid) t2 >> これは$wpdb->zaimumasterテーブルをsecidでグループ化した上でsecidとmax(intperiod)のかりそめのテーブルを作成し一意の情報を作っているイメージでしょうか? 加えてとなりますが、max(intperiod) intperiodの2つ目のintperiodの意味しているところもわかりませんでした。。。またt2でこの新しいテーブルを明示している。。? 3.using(secid,intperiod) where t1.secid=%d",$secid >>これは$wpdb->zaimumasterテーブルのうち$secidが指定のものと一致する条件で且つ、上記で作成した新しいテーブルの一意のものと一致するものを指定する意味でしょうか? わかりづらくて大変申し訳御座いませんが、もしご親切にそれぞれの句の意味を噛み砕いてご教示を下されば本当に嬉しいです。。 何卒、よろしくお願い申し上げます。
A.Ichi

2016/10/15 11:38

沢山コメント頂いたのも知らずに修正していました。SQLの部分のみテストしました。修正を載せました。
SugiuraY

2016/10/15 11:52

ありがとうございます、勉強をさせていただきます。
A.Ichi

2016/10/15 12:16

簡単ですがお答えを書きました。 ご質問(1) t1.* はJOINするテーブルのどちらかのテーブルの全項目を示しています。t1 join t2のときに明示的にテーブルを指定しました。 t ご質問(2) max(intperiod) intperiodは、正しく書くとmax(intperiod) AS intperiod です。手抜きですみません。 サブクエリはメモリ上に仮に作成されるテーブルと思って頂いてよいと思います。よくインデックスが 利かないので遅くなる原因となるものです。 ご質問(3) サブクエリの結果とJOINして一致するものを抽出しています。比較するusingは項目名が同じ場合に使います。 ON の場合 t1.aaa = t2.aaa and t1.bbb = t2.bbb と書きます。比較項目名が異なる場合はONです。
SugiuraY

2016/10/15 23:10

お手数をおかけして、申し訳ございません。かなりクリアになりました。 改めてお力添えに感謝を申し上げます。 宜しくお願い申し上げます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問