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

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

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

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

PHP

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

Q&A

解決済

2回答

2460閲覧

PHP DBからカウントしながら日付で抽出

mi_

総合スコア80

MySQL

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

PHP

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

0グッド

0クリップ

投稿2017/01/22 11:52

お世話になります。

引き続きアンケートの機能の作成でてこずっています。

テーブル名 an
an_no 自動で番号が入ります

an_time 回答したタイムスタンプ

an_key 親回答からの番号が入っています

an_data 回答内容が文字で入っています。

下記の内容のSQL文で、同じ回答だった場合(文字が同じ)に、カウントして、後の処理で件数が表示できています。
たとえばA市3件といった感じです。

これに、日付で抽出を加えようと、
$sql='SELECT an_data ,count(an_data) FROM an group by an_data';の文を
$sql='SELECT *,count(an_data) FROM an group by an_data,an_time HAVING (an_time) BETWEEN :before AND :after';のように変えたところ、
抽出内容は一見同じで日付で絞込ができたように見えますが、
A市2件であるべきところがA市1件に減ってしまいます。他の重複して件数が複数でないといけないところも全部1件になってしまいます。

このSQLの使い方はそもそも問題があるのでしょうか?
違う方法でもいいので、カウントと、日付による絞り込みができたらと思います。

分かりにくくて申し訳ないですが、お知恵をお借りしたいと思います。
よろしくお願いします。

require_once( __DIR__.'/common/database.php' ); $dbh=new PDO($dsn,$dbUser,$dbPass); $dbh->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION); $dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES, false); //回答の集計をしたい部分です HAVING BETWEENの行を使うと・・・ //$sql='SELECT *,count(an_data) FROM an group by an_data,an_time HAVING (an_time) BETWEEN :before AND :after'; $sql='SELECT an_data ,count(an_data) FROM an group by an_data'; $stma=$dbh->prepare($sql); $stma->bindValue(':before',$before,PDO::PARAM_STR); $stma->bindValue(':after',$after,PDO::PARAM_STR); $stma->execute(); while(true) { $reca=$stma->fetch(PDO::FETCH_ASSOC); if($reca==false) { break; } $key=$reca['an_key']; $key2=$reca['an_data']; $count_kaitou[$key][$key2]=$reca['count(an_data)']; } //後の処理で、$count_kaitouから内容を表示したりしています。

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

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

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

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

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

guest

回答2

0

ベストアンサー

多分質問者様がしたいことをSQLに表すと、

SQL

1SELECT 2 * 3, count(an_data) 4FROM 5 an 6GROUP BY 7 an_data 8, an_time 9HAVING 10 (an_time) BETWEEN :before AND :after

これは誤りで下記に直す必要があるのかなと推測します。
(※コメントに注釈を書いたので意識してみてください)

SQL

1SELECT 2 an_data 3/* 下のようにGROUP BY指定してない項目を単純に指定するのはNG 4 * どうしても取りたいなら「MAX(an_no) AS an_no」みたいに集約関数を噛ませましょう。 5 */ 6-- * 7, count(an_data) 8FROM 9 an 10WHERE 11 an_time BETWEEN :before AND :after 12GROUP BY 13 an_data 14/* 下のように集約単位は変えちゃいけないはず・・・ */ 15-- , an_time 16/* 集約関数噛ませたものに条件指定するのでなければ、 17 * HAVING句は必要ないでありますよ、隊長! 18 */ 19-- HAVING 20-- (an_time) BETWEEN :before AND :after 21

投稿2017/01/22 13:53

編集2017/01/22 13:55
Panzer_vor

総合スコア1636

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

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

mi_

2017/01/22 14:05

ご提示いただいた内容で、重複した名前と、その名前毎の件数がとれて、日付で抽出もできました! コメント頂いた内容しっかり理解して、時々見返したいと思います。この内容が1行にまとまるところ、SQLのすごさにびっくりします。ありがとうございました。
Panzer_vor

2017/01/22 14:19

> mi_さん SQLも他の言語と同じく出来ることが増えてくると楽しいですよ。 覚えるべきことは多いかもしれませんが、 トライアンドエラーで試行錯誤しながら是非力を付けていってください。 どうしても煮詰まった際には、 経緯と問題点、試したことをうまく提示して質問できるようになれば、 より的確な回答も付きやすくなるでしょう。
mi_

2017/01/22 14:37

ありがとうございます! みなさんに回答いただき、直接助けてもらっていますし、視野も広がって助かっています。 煮詰まった際の、質問の仕方も、冷静になってよく考えるようにしたいと思います。
guest

0

$stma->fetch(PDO::FETCH_ASSOC) をループしていないからでは?

投稿2017/01/22 12:07

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

mi_

2017/01/22 12:18

いつもありがとうございます。 上記では、あまりいいループにはならないでしょうか? 抽出の仕方をかえてしまったので、後の処理もがらりと変えなければいけないということでしょうか?
退会済みユーザー

退会済みユーザー

2017/01/22 13:07 編集

いったい何を参考に書いて、このソースになったんだろうと思うくらい、謎な仕様です。 SQLについてはノーチェックです。テーブル定義も不明だし、中に入っているでたーも提示されていないので実行不可能。プログラム上のおかしなところは見ればわかるが、それ以外は読んでいません。
Panzer_vor

2017/01/22 13:43

横槍ですが、 修正後のSQL自体本当だと構文エラーとなる書き方なんですよね・・・^^; MySQLだから動くには動きますが、 なるべくGROUP BY句を利用した際に、 SELECT項目にはどういったものが集約関数噛ませずに指定できる・できないを抑えてもらいたい所・・・
mi_

2017/01/22 13:46

Kosuke_Shibuya様 なんとか動きそうとおもって、固執してしまい、知識もないままどんどん複雑にしてしまっておりました。お恥ずかしい限りです。 Panzer_vor様 構文エラーとなるような内容なのですね。おっしゃるところを考えてみたいと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問