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

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

ただいまの
回答率

90.51%

  • PHP

    23978questions

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

  • WordPress

    8914questions

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

  • MySQL

    6978questions

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

  • PDO

    381questions

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

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

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 1,590

SugiuraY

score 201

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

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)
```

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • timy

    2016/10/15 17:11

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

    キャンセル

  • SugiuraY

    2016/10/15 17:18

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

    キャンセル

  • A.Ichi

    2016/10/15 19:07

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

    キャンセル

回答 1

checkベストアンサー

0

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

$secid=100;
$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");
$stmt->bindValue(':secid',$secid));
$status = $stmt->execute();
if (!$status) {
   $err = $stmt->errorInfo();
}
$rec=$stmt->fetch(PDO::FETCH_ASSOC);
print_r ($rec);

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

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

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/10/15 17:57

    ご回答いただき、ありがとうございます。
    今、ご教示いただいた内容で、エラーが出ているので、細かいコードを見直しているのですが、先に確認させていただきたいのですが、

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

    キャンセル

  • 2016/10/15 18:38

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

    キャンセル

  • 2016/10/15 19:10

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

    キャンセル

  • 2016/10/15 19:15

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

    キャンセル

  • 2016/10/15 19:25

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

    キャンセル

  • 2016/10/15 19:32

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

    キャンセル

  • 2016/10/15 19:35

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

    キャンセル

  • 2016/10/15 19:45

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

    キャンセル

  • 2016/10/15 19:55

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

    キャンセル

  • 2016/10/15 20: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が指定のものと一致する条件で且つ、上記で作成した新しいテーブルの一意のものと一致するものを指定する意味でしょうか?

    わかりづらくて大変申し訳御座いませんが、もしご親切にそれぞれの句の意味を噛み砕いてご教示を下されば本当に嬉しいです。。

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

    キャンセル

  • 2016/10/15 20:38

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

    キャンセル

  • 2016/10/15 20:52

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

    キャンセル

  • 2016/10/15 21: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です。

    キャンセル

  • 2016/10/16 08:10

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

    キャンセル

同じタグがついた質問を見る

  • PHP

    23978questions

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

  • WordPress

    8914questions

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

  • MySQL

    6978questions

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

  • PDO

    381questions

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