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

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に必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

PHP

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

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

Q&A

解決済

2回答

3666閲覧

PHP・MySQLでチェックボックスを使用して複数カラムを対象にデータを絞り込む方法

tanakanakanaka

総合スコア1

MySQL

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

SQL

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

PHP

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

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

0グッド

1クリップ

投稿2021/04/25 13:53

編集2021/04/26 13:37

前提

・昨日XAMPPを入れて初めてPHP、SQL、HTMLを触ったプログラミング歴2日の超初心者です。
・ソシャゲのカードをレアリティや属性などからチェックボックで絞り込んで表を表示するサイトがほしくて、以下のようなものをほぼインターネットからのコピペで作りました。(実際はもっとデータ量があり、カラム数ももう少し多いです)

#####1.MySQLのデータベース(テーブル名はcardlistです)

norealitycharactertype1type2type3type4type5type6type7type8
0001Nキャラ1属性4属性17属性39属性62属性82
0002Rキャラ1属性22属性26属性36属性43属性45属性73属性84
0003SRキャラ1属性6属性24属性37属性44属性47属性53属性58
0004SSRキャラ1属性2属性32属性42属性47属性49属性79属性84属性90
0005Nキャラ2属性1属性17属性38属性59属性69属性76
0006Rキャラ2属性18属性24属性35属性49属性56属性74
0007SRキャラ2属性14属性50属性51属性53属性57属性63属性90
0008SSRキャラ2属性1属性7属性19属性66属性69属性70属性75属性90

こんな感じに属性が各カード最大8個ついていて、個数はカードによって違います。
属性はたくさん種類があり、今後も増えると思います。
キャラも実際にはもっとたくさんいます。
type1~8に区別はないです。(各属性はどのカラムにも入る可能性がある)

#####2.HTML(cardsearch.phpに書いています)

html

1 <form action="cardsearch.php" method="POST"> 2 <h3>レア</h3> 3 <p> 4 <label><input type="checkbox" name="reality[]" value="N">N</label> 5 <label><input type="checkbox" name="reality[]" value="R">R</label> 6 <label><input type="checkbox" name="reality[]" value="SR">SR</label> 7 <label><input type="checkbox" name="reality[]" value="SSR">SSR</label> 8 </p> 9 <h3>キャラ</h3> 10 <p> 11 <label><input type="checkbox" name="character[]" value="キャラ1">キャラ1</label> 12 <label><input type="checkbox" name="character[]" value="キャラ2">キャラ2</label> 13 <label><input type="checkbox" name="character[]" value="キャラ3">キャラ3</label> 14 </p> 15 <h3>属性</h3> 16 <p> 17 <label><input type="checkbox" name="type[]" value="属性1">属性1</label> 18 <label><input type="checkbox" name="type[]" value="属性2">属性2</label> 19 <label><input type="checkbox" name="type[]" value="属性3">属性3</label> 20     長いので中略 21 <label><input type="checkbox" name="type[]" value="属性88">属性88</label> 22 <label><input type="checkbox" name="type[]" value="属性89">属性89</label> 23 <label><input type="checkbox" name="type[]" value="属性90">属性90</label> 24 </p> 25 <p> 26 <input type="submit" value="絞り込み"> <input type="reset" value="リセット"> 27 </p>

属性は多いので最終的には折りたたみとかでいい感じにまとめる予定です。
#####3.PHP(上のHTMLの真下に書いてあります)

php

1<?php 2$where=""; 3//$whereは変数で、中身が空 4foreach((array) $_REQUEST['reality'] as $key=>$reality){ 5//$_REQUEST['reality']がレアで選択したデータ 6//$keyと$realityは変数なのは分かるが詳細不明、$_REQUEST['reality']が入っている?$keyと$realityの違いは? 7 if($key==0) $where.=" AND (0"; 8 //レアで選択したデータが0個のとき、「 AND (0」が出力される? 9 $where .= " OR `reality`='".$reality."'"; 10 //不明 11 if($key==count($_REQUEST['reality'] ) -1) $where.=")"; 12 //レアで選択したデータの数を数えている?「)」を出力するのは分かるが、-1が分からない 13 //選択が0個なら$where= AND (0)になる? 14 } 15foreach((array) $_REQUEST['character'] as $key=>$character){ 16 if($key==0) $where.=" AND (0"; 17 $where .= " OR `character`='".$character."'"; 18 if($key==count($_REQUEST['character'] ) -1) $where.=")"; 19 } 20 $sql = "SELECT * FROM cardlist WHERE 1".$where; 21 //cardlistを取得、$whereで絞り込み条件の設定が行われている 22 //WHERE 1は何も絞り込みがなかったときに全件表示させるためのものらしいので、WHERE 1 AND (0)は絞り込み条件なしということ? 23 $stmt = $dbh->query( $sql ); 24 //$dbhはログイン情報が入っている 25 //$dbhでcardlistにアクセス、$sql(SELECT~の実行結果)が$stmtに入る 26 echo "<table>\n"; 27 echo "\t<thead><tr><th>No.</th><th>レア</th><th>キャラ</th><th colspan=8>属性</tr></thead>\n"; 28 while( $result = $stmt->fetch( PDO::FETCH_ASSOC ) ){ 29 //ループ処理らしいが詳細不明 30 echo "\t<tbody><tr>\n"; 31 echo "\t\t<td>{$result['no']}</td>\n"; 32 echo "\t\t<td>{$result['reality']}</td>\n"; 33 echo "\t\t<td>{$result['character']}</td>\n"; 34 echo "\t\t<td>{$result['type1']}</td>\n"; 35 echo "\t\t<td>{$result['type2']}</td>\n"; 36 echo "\t\t<td>{$result['type3']}</td>\n"; 37 echo "\t\t<td>{$result['type4']}</td>\n"; 38 echo "\t\t<td>{$result['type5']}</td>\n"; 39 echo "\t\t<td>{$result['type6']}</td>\n"; 40 echo "\t\t<td>{$result['type7']}</td>\n"; 41 echo "\t\t<td>{$result['type8']}</td>\n"; 42 echo "\t</tr></tbody>\n"; 43 } 44 echo "</table>\n"; 45 //これで絞り込み結果を表で表示できる 46 ?>

属性の絞り込みは未実装です。(これの実装方法が質問です。)
HTMLとPHPは以下のページをコピペして少し変えただけなので仕組みがあまり分かっていません。
phpのチェックボックスによる絞込みについて -PHPとSQLでチェックボッ- PHP | 教えて!goo https://oshiete.goo.ne.jp/qa/7153577.html
コメントで自分の理解を書いてみました。

#####4.CSS
今回の質問には不要だと思うので省略します。
また、装飾関係でやりたいことがあったためjQueryをbodyの一番下に入れています。

###チェックボックスの仕様
同じカラムのチェックボックスを複数つけるとOR検索に、違うカラム同士はAND検索になるようになっています。
何にもチェックを入れないと全てを表示します。
(例)
レアのNとRにチェックを入れて絞り込みを押すと0001、0002、0005、0006が出る
レアのNとR、キャラのキャラ1にチェックを入れて絞り込みを押すと0001、0002が出る

###解決したいこと
属性にチェックを入れて絞り込めるようにしたいです。
属性に複数チェックを入れたときはキャラやレアとは違いAND検索にして、チェックを入れた全ての属性を持つカードを表示したいです。
他のカラム同士とは現在の仕様と同じくAND検索になるようにしたいです。
(例)
属性1にチェックを入れて絞り込みを押すと0005、0008が出る
属性1と属性17にチェックを入れて絞り込みを押すと0005が出る
レアのNと属性1にチェックを入れて絞り込みを押すと0005が出る
レアのRと属性1にチェックを入れて絞り込みを押すと何も出ない

同じ結果が得られればテーブルの構造などが変わっても大丈夫です。
最終的には無料のレンタルサーバーを使って他のプレイヤーに公開したいです。

試したこと

「複数カラム 絞り込み」などのワードで調べましたが思うようなものは見つかりませんでした。

補足情報(FW/ツールのバージョンなど)

どこの何を答えるべきか分からないので省略します。

おそらく初歩的な部分で躓いているのだと思いますが、回答よろしくお願いします。

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

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

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

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

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

guest

回答2

0

個人や企業などの著作物を拝借してコンテンツを作ることの法的責任などはこの際置いときます、
専門家じゃないので。

そういうデータ構造で絞り込み表示をしたいってことなんですが、
たまたまそういうふうに見えていたデータ構造なので、
そのままの構造で絞り込み表示を実現するのってたぶん大変です。

type1~8までどこに何が入っているかもわからない、
テーブル構造も示されていないし、インデックスもどこまで仕込まれているかわからないのだけど、
たぶんクエリーは膨大な場合分け分岐の塊になって
スルスルッとは出てこないと思います。

データ・モデルを安定させる | Think IT(シンクイット)

データ構造の最適化、テーブルの正規化などして、
データ構造を抽出しやすく見直しつつ、
表示の仕方を工夫するのをやらないと
時間(や金)があってもとてもやる気にならないなと。

私がやるなら、
キャラだけのリストをテーブル化、
レア度をテーブル化、
それぞれの属性に関する情報をまとめる属性テーブル化を経て、
キャラxレア度x属性の存在する/しないをつなぐ中間テーブルを設けますかね。
(本当は図に起こして説明したらいいけど、あとで時間が取れたら考えます。)

投稿2021/04/26 01:22

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

tanakanakanaka

2021/04/26 13:34

ありがとうございます。 やはりテーブルから駄目なんですね。 正規化勉強します。
guest

0

ベストアンサー

やり方的にはsetやenumが楽ですが、あとから変更するのが面倒です
正規化して属性を管理するか、属性をjson型にするかで対応するとよいでしょう

sample

SQL

1 2create table tbl (id int primary key , 3no varchar(10), 4reality varchar(10), 5`character` varchar(10), 6attribe json 7); 8 9insert into tbl values 10(1,'0001','N','キャラ1','[4,17,39,62,82]'), 11(2,'0002','R','キャラ1','[22,26,36,43,45,73,84]'), 12(3,'0003','SR','キャラ1','[6,24,37,44,47,53,58]'), 13(4,'0004','SSR','キャラ1','[2,32,42,47,49,79,84,90]'), 14(5,'0005','N','キャラ2','[1,17,38,59,69,76]'), 15(6,'0006','R','キャラ2','[18,24,35,49,56,74]'), 16(7,'0007','SR','キャラ2','[14,50,51,53,57,63,90]'), 17(8,'0008','SSR','キャラ2','[1,7,19,66,69,70,75,90]'); 18 19-- (1) 20SELECT * FROM tbl 21WHERE reality in('N','R'); 22 23-- (2) 24SELECT * FROM tbl 25WHERE reality in('N','R') and `character` ='キャラ1'; 26 27-- (3) 28SELECT * FROM tbl 29WHERE JSON_CONTAINS(attribe,'1'); 30 31-- (4) 32SELECT * FROM tbl 33WHERE JSON_CONTAINS(attribe,'1') and JSON_CONTAINS(attribe,'17'); 34 35-- (5) 36SELECT * FROM tbl 37WHERE reality='N' and JSON_CONTAINS(attribe,'1'); 38 39-- (6) 40SELECT * FROM tbl 41WHERE reality='R' and JSON_CONTAINS(attribe,'1');

投稿2021/04/26 01:00

編集2021/04/26 11:39
yambejp

総合スコア115010

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

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

tanakanakanaka

2021/04/26 13:26

ありがとうございます。 WHEREのカラム名と検索値をチェックボックスの選択結果から取得できれば属性の複数選択での完全一致検索はこれで行けそうですね。 チェックボックスのデータの取得は質問文に記載したPHPのforeachのところを改造すれば可能でしょうか? foreach((array) $_REQUEST['type'] as $key=>$type){ if($key==0) $where.=" AND (0"; $where .= " AND JSON_CONTAINS(attribe, '".$type."'"; if($key==count($_REQUEST['type'] ) -1) $where.=")"; } さすがにこんな単純な改造ではないですよね…
yambejp

2021/04/26 13:31

ポイントは属性がAND検索なのに対して、レアやキャラクタがOR検索なところです。 それさえ理解すればあとは処理をあてこむだけです
yambejp

2021/04/26 13:44 編集

こんな感じ <?PHP $r=filter_input(INPUT_POST,"reality",FILTER_DEFAULT,FILTER_REQUIRE_ARRAY); $c=filter_input(INPUT_POST,"character",FILTER_DEFAULT,FILTER_REQUIRE_ARRAY); $t=filter_input(INPUT_POST,"type",FILTER_DEFAULT,FILTER_REQUIRE_ARRAY); $sql="SELECT * FROM tbl WHERE 1 "; $data=[]; if(!is_null($r)){ $sql.="AND reality in(".implode(",",ARRAY_FILL(0,count($r),"?")).") "; $data=array_merge($data,$r); } if(!is_null($c)){ $sql.="AND `character` in(".implode(",",ARRAY_FILL(0,count($c),"?")).") "; $data=array_merge($data,$c); } if(!is_null($t)){ $sql.=str_repeat(" AND JSON_CONTAINS(attribe,?) ",count($t)); $data=array_merge($data,$t); } print $sql.";<br>\n"; print_r($data); ?> <hr> <form method="POST"> <h3>レア</h3> <p> <label><input type="checkbox" name="reality[]" value="N">N</label> <label><input type="checkbox" name="reality[]" value="R">R</label> <label><input type="checkbox" name="reality[]" value="SR">SR</label> <label><input type="checkbox" name="reality[]" value="SSR">SSR</label> </p> <h3>キャラ</h3> <p> <label><input type="checkbox" name="character[]" value="キャラ1">キャラ1</label> <label><input type="checkbox" name="character[]" value="キャラ2">キャラ2</label> <label><input type="checkbox" name="character[]" value="キャラ3">キャラ3</label> </p> <h3>属性</h3> <p> <label><input type="checkbox" name="type[]" value="1">属性1</label> <label><input type="checkbox" name="type[]" value="2">属性2</label> <label><input type="checkbox" name="type[]" value="3">属性3</label> </p> <input type="submit" value="send"> </form>
tanakanakanaka

2021/04/29 11:08

コードありがとうございます! 最初の回答でいただいた属性をJSON型にする案を採用し、attribeカラムに「["属性4","属性17","属性39","属性62","属性82"]」という書き方で属性を入れて、コードは自分が質問文に書いた教えてgooからコピペしたコードを以下のように改造することにしました。 foreach((array) $_REQUEST['attribe'] as $key=>$attribe){ $where .= " AND JSON_CONTAINS(attribe,"."'\"".$attribe."\"')"; } 最適解はいただいたコードなのかもしれないですが、これで求めていた動作はしているので自分が構造を理解できていることを優先してこれでいきます。 ありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.46%

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

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

質問する

関連した質問