teratail header banner
teratail header banner
質問するログイン新規登録
SQL

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

PHP

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

Q&A

解決済

2回答

716閲覧

(PHP, mysql) 店ごとの売上合計を出す為のSQL文の書き方を教えて頂きたいです

emi_ono

総合スコア84

SQL

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

PHP

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

0グッド

0クリップ

投稿2024/02/02 09:07

編集2024/02/03 06:52

0

0

実現したいこと

店舗ごとに指定した月の売上合計(カラムmenu_price合計値)を一覧にしたいです。

テーブルとカラム

【shopテーブル】
店舗名やパスワードなど店舗のログイン情報を管理しています
このテーブルで作られたshop_id(店舗ID)が他のテーブルに紐づきます

  • shop_name(店舗名)varchar(255)
  • created(作成日)varchar(50)
  • shop_id(店舗ID)int(11)AUTO_INCREMENT

【listテーブル】
店舗の営業時間やメニューなど店舗情報を管理しています

  • type_of_contract(契約タイプ)int(11)
  • shop_id(店舗ID)int(11)

【customer3テーブル】
予約情報を管理しています

  • menu_price(料金)int(11)
  • reserve_day(予約日)date
  • start_time(予約時間)datetime
  • shop_id(店舗ID)int(11)

発生している問題・分からないこと

formから条件(契約タイプと対象の月)を受けとり、その条件に合った店舗を店舗毎の対象月に入った予約件数と共に一覧表示する事はできたのですが、カラムmenu_priceの合計値を表示する事ができません。

  1. <form>で条件を受け取る
  2. その条件の店舗を(テーブル:shop、list)から取得
  3. 取得した店舗をforを使って表示
  4. forの中で店舗ごとの予約内容を(テーブル:customer3)から取得

この流れでできるかなと考えました。

menu_price合計値を取る為に

  • SUM(menu_price) AS P,
  • $rec = $prepare->fetch(PDO::FETCH_ASSOC);
  • echo "<p>".$rec['SUM(P)']."</p>";
    を追加しました。

これらを設定する前は下記の画像のように表示されるのですが(変数の値も正確に表示されています)
SUM()などを設定する前
設定した後は下記の画像のように表示されます
SUM()などを設定した後

このように繰り返しの最初の1回だけは変数の値が表示されるのですが、$count_customerの値が違います(20が正しいです)。またそれ以降は変数部分が表示されず、$count_customerの値も違います。繰り返しは出来ているようで、変数以外は期待する回数(ここでは13回)繰り返し表示されます。

要領を得ない説明で大変申し訳ありません。
アドバイスを頂けると助かります。よろしくお願いします。

該当のソースコード

PHP

1<?php 2//エスケープ処理 3function h($item) { 4 if (is_array($item)) { 5 return array_map("h", $item); 6 } else { 7 return htmlspecialchars($item, ENT_QUOTES); 8 } 9} 10require_once( '../core/config.php' ); 11$thisMonth = date( 'n' ); 12$lastMonth = date('n', strtotime(date("Y-m-01") . ' -1 month')); 13$twoMonth = date('n', strtotime(date("Y-m-01") . ' -2 month')); 14$threeMonth = date('n', strtotime(date("Y-m-01") . ' -3 month')); 15?> 16<form method="post" action=""> 17<p class="item"> 18 <label>契約タイプを選択</label> 19 <select name="type_of_contract" required> 20 <option value="">選択してください</option> 21 <option value="1">定額</option> 22 <option value="2">都度</option> 23 <option value="3">全て</option> 24 </select> 25</p> 26<p class="item"> 27 <label>対象の月を選択</label> 28 <select name="mode" required> 29 <option value="">選択してください</option> 30 <option value="thisMonth"><?php echo $thisMonth; ?></option> 31 <option value="lastMonth"><?php echo $lastMonth; ?></option> 32 <option value="twoMonth"><?php echo $twoMonth; ?></option> 33 <option value="threeMonth"><?php echo $threeMonth; ?></option> 34 </select> 35</p> 36<input type="submit" value="送信"> 37</form> 38</div> 39 40<?php 41$_POST["mode"] == ""; 42 43$mode = h($_POST["mode"]); 44$type_of_contract = h($_POST["type_of_contract"]); 45if($type_of_contract == ""){ 46 $type_of_contract = "3"; 47} 48try { 49 // PDOインスタンスを生成 50 $dbh = new PDO( DSN, DB_USER, DB_PASS ); 51 $dbh->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION ); 52 53 $sql = "SELECT 54 s.shop_name, 55 s.shop_id, 56 s.created, 57 l.type_of_contract 58 FROM 59 shop s 60 INNER JOIN 61 list l 62 ON 63 s.shop_id = l.shop_id 64 where 65 NOT ( s.shop_id = 1 or s.shop_id = 2 or l.type_of_contract = 0 ) 66 "; 67 switch ( $type_of_contract ) { 68 case "1": 69 $typeStr = "定額"; 70 $sql = $sql . " AND l.type_of_contract = 1 ORDER BY s.shop_id;"; 71 break; 72 case "2": 73 $typeStr = "都度"; 74 $sql = $sql . " AND l.type_of_contract = 2 ORDER BY s.shop_id;"; 75 break; 76 case "3": 77 $typeStr = "全て"; 78 $sql = $sql . " ORDER BY s.shop_id;"; 79 break; 80 } 81 82 $prepare = $dbh->prepare( $sql ); 83 $prepare->execute(); 84 $count = $prepare->rowCount(); //データ数を取得 85 $rec = $prepare->fetchAll(PDO::FETCH_ASSOC); 86 //var_dump($rec); 87 88 echo "<h2>【".$typeStr."】件数:".$count."</h2>"; 89 90 for($i = 0; $i < $count; $i++){ 91 $shop_name = $rec[$i]['shop_name']; 92 $shop_id = $rec[$i]['shop_id']; 93 $type_of_contract = $rec[$i]['type_of_contract']; 94 //予約内容 95 $sql = "SELECT 96 SUM(menu_price) AS P, 97 reserve_day, 98 start_time 99 FROM 100 customer3 101 WHERE 102 shop_id = :shop_id 103 "; 104 switch ( $mode ) { 105 case "thisMonth": 106 $modeStr = $thisMonth . "月"; 107 $sql = $sql . " AND DATE_FORMAT(reserve_day, '%Y%m') = DATE_FORMAT(NOW(), '%Y%m') ORDER BY start_time"; 108 break; 109 case "lastMonth": 110 $modeStr = $lastMonth . "月"; 111 $sql = $sql . " AND DATE_FORMAT(reserve_day, '%Y%m') = DATE_FORMAT(CURDATE() - INTERVAL 1 MONTH, '%Y%m') ORDER BY start_time"; 112 break; 113 case "twoMonth": 114 $modeStr = $twoMonth . "月"; 115 $sql = $sql . " AND DATE_FORMAT(reserve_day, '%Y%m') = DATE_FORMAT(CURDATE() - INTERVAL 2 MONTH, '%Y%m') ORDER BY start_time"; 116 break; 117 case "threeMonth": 118 $modeStr = $threeMonth . "月"; 119 $sql = $sql . " AND DATE_FORMAT(reserve_day, '%Y%m') = DATE_FORMAT(CURDATE() - INTERVAL 3 MONTH, '%Y%m') ORDER BY start_time"; 120 break; 121 } 122 123 $prepare = $dbh->prepare( $sql ); 124 $prepare -> bindValue(':shop_id', $shop_id, PDO::PARAM_INT); 125 $prepare->execute(); 126 $count_customer = $prepare->rowCount(); //データ数を取得 127 $rec = $prepare->fetch(PDO::FETCH_ASSOC); 128 129 130 echo '<p>契約タイプ:'.$type_of_contract.'</p>'; 131 echo '<p>('.$shop_id.')'.$shop_name.'</p>'; 132 echo '<p>'.$count_customer.'件</p>'; 133 echo "<p>".$rec['P']."</p>"; 134 135 136 137 echo '<hr>'; 138 } 139}catch ( PDOException $e ) { 140 // エラーメッセージを表示させる 141 echo 'データベースにアクセスできません!' . $e->getMessage(); 142 // 強制終了 143 exit; 144}finally{ 145 //データベース接続切断 146 $stmt = null; 147 $dbh = null; 148} 149?> 150

試したこと・調べたこと

  • teratailやGoogle等で検索した
  • ソースコードを自分なりに変更した
  • 知人に聞いた
  • その他
上記の詳細・結果

SUM関数を使うと合計値を取得できる
PDO::FETCH_ASSOCを指定するとカラム名が添え字”となる配列で取得できる

補足

特になし

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

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

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

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

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

gklipxhh

2024/02/02 13:26 編集

テーブル定義が不明です。 テーブルの意味とカラムの意味が他人に伝わるように具体的に全て書いて下さい。
emi_ono

2024/02/02 14:30

コメントありがとうございます。 テーブルの説明を修正しました。
guest

回答2

0

自己解決

2回目に出てくるPDOの変数名を

php

1$rec = $prepare->fetch(PDO::FETCH_ASSOC);

から

php

1$rec2 = $prepare->fetch(PDO::FETCH_ASSOC);

のように変更する事で解決できました。
ありがとうござます。

投稿2024/02/07 06:16

編集2024/02/07 06:19
emi_ono

総合スコア84

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

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

0

SQL がSUM(menu_price) AS P になっているので連想配列のキーに指定する文字列はPではないでしょうか?

diff

1- echo "<p>".$rec['SUM(P)']."</p>"; 2+ echo "<p>".$rec['P']."</p>";

投稿2024/02/02 14:43

gklipxhh

総合スコア36

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

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

emi_ono

2024/02/03 03:52

ありがとうございます! 試してみたのですが結果は同じでダメした。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.30%

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

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

質問する

関連した質問