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

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

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

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

PHP

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

Q&A

解決済

6回答

1615閲覧

PHP+MySQLで、1つあるいは2つの条件指定でSQLを実行する事はできますか?

CheGuella

総合スコア11

MySQL

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

PHP

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

0グッド

1クリップ

投稿2018/06/21 05:36

PHP+MySQLでコードを書いていて、ユーザーが入るテーブルを使ってWebアプリを作っているところです。
以下のようないくつかの指定した条件(キーワード、カテゴリー、ユーザーランク等)で検索する方法はありますでしょうか?

・指定なし->(全件)
・キーワードで検索
・カテゴリーで検索
・ユーザーランクで検索
・キーワードとカテゴリーで検索
・キーワードとユーザーランクで検索
・カテゴリーとユーザーランクで検索

現在以下のような形で、if文で振り分けて実装していますが、これを1文のSQLでおこなうことはできないものでしょうか?

if (empty($name) && empty($category) && empty($rank)) {
$sql = "SELECT * FROM user";
} elseif ($name && empty($category) && empty($rank)) {
$sql = "SELECT * FROM user WHERE name like '%$name%'";
} elseif ($name && $category && empty($rank)) {
$sql = "SELECT * FROM user WHERE name like '%$name%' AND category = '$category'";
}

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

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

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

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

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

sazi

2018/06/21 05:42

1文でとは分岐無しでということですか?
CheGuella

2018/06/21 05:46

仰る通りです。理想はphpによるif文無しで、sql文のみで実装できないものか気になった次第です。
m.ts10806

2018/06/21 05:47

あ、そういうこと・・・。
退会済みユーザー

退会済みユーザー

2018/06/21 06:00

できなくはないけど、SQLのメンテめんどくさくなるから、自分ならやらないですねー
CheGuella

2018/06/21 06:05

ありがとうございます。たしかにそう考えると仰る通りですね。
guest

回答6

0

「素のSQL文を自分で生成しないといけない」という条件でよく使う技としては、

  • 条件ごとにSQLの条件の断片を生成して配列に入れていく
  • それを) AND (implodeして、前後にカッコも付けて1本の条件にする

というような方法があります。

もっとも、実用上は何かしらのクエリ生成用のライブラリを使うのが正解かもしれません。

投稿2018/06/21 05:47

編集2018/06/21 05:58
maisumakun

総合スコア145062

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

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

m.ts10806

2018/06/21 05:56

勘違いしていたらすみません。explodeだと文字列を分割して配列にしてしまうのでは。
maisumakun

2018/06/21 06:00

すみません、うっかりミスでした(修正しました)。
guest

0

ベストアンサー

配列に条件を突っ込んで最後にimplodeでandでつなげば良いです。

※未検証につき実装イメージとして捉えてください。rankも適当に足してあります

php

1$where = ""; 2$where_array = []; 3if(!empty($name)){ 4 $where_array[] = "name like '%$name%'"; 5} 6if(!empty($category)){ 7 $where_array[] = "category = '$category'"; 8} 9if(!empty($rank)){ 10 $where_array[] = "rank = '$rank'"; 11} 12if(count($where_array) > 0){ 13 $where = " where ".implode(" and ",$where_array); 14} 15 16$sql = "SELECT * FROM user".$where;

投稿2018/06/21 05:46

m.ts10806

総合スコア80731

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

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

0

この手の処理はWHERE句にANDでつなげていくのが基本です

PHP

1<?PHP 2foreach(["name","category","rank"] as $val){ 3 $$val=filter_input(INPUT_POST,$val); /*詳しいバリデートが必要なら処理を分ける*/ 4} 5$sql = ""; 6$data=[]; 7if(!is_null($name)){ 8 $sql = "SELECT * FROM user "; 9 if($name!==""){ 10 $sql.= "AND `name` like ? "; 11 $data[]="%".$name."%"; 12 } 13 if($category!==""){ 14 $sql.= "AND `category`=? "; 15 $data[]=$category; 16 } 17 if($rank!==""){ 18 $sql.= "AND `rank`=? "; 19 $data[]=$rank; 20 } 21} 22print $sql.";<br>\n"; 23print_r($data); 24 25?> 26<form method="post"> 27name:<input type="text" name="name"><br> 28category:<input type="text" name="category"><br> 29rank:<input type="text" name="rank"><br> 30<input type="submit" value="search"><br> 31</form>

上記を$sqlをpdoでprepareに投げて処理してください

投稿2018/06/21 06:26

yambejp

総合スコア114503

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

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

0

検索条件をユーザー定義変数を経由するようにして、条件がない場合にはユーザー定義変数をNUllにします。

その上で、以下のような記述にすればSQL作成用の分岐は不要です。

SQL

1SELECT * FROM user 2-- WHERE name like concat('%', coalesce(@name, name), '%') 3WHERE case when @name is not null then name like concat('%', @name, '%') else True end 4 AND category = coalesce(@category,category)

但し、条件に応じたSQLと比較すると、性能が落ちるだろう事が予想されます。

投稿2018/06/21 06:03

編集2018/06/21 06:19
sazi

総合スコア25076

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

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

sazi

2018/06/21 06:11

データによっては、パラメータ省略時のlikeは違う条件のものを取ってきちゃうので駄目ですね。。
sazi

2018/06/21 06:31 編集

修正しました。結局、分岐はSQLに移動しているだけなので、動的に生成する方が吉ですね。
guest

0

条件によって実行するSQLを使い分けては?フロー制御関数

投稿2018/06/21 05:50

Orlofsky

総合スコア16415

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

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

0

サンプル

php

1<?php 2 3$dsn = "mysql:host=licalhost;dbname=sample;charset=utf8mb4"; 4$username = "root"; 5$password = "password"; 6$options = [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]; 7$pdo = new PDO($dsn, $username, $password, $options); 8 9$params = []; 10$sql = "SELECT * FROM user WHERE 1 "; 11 12if ($name) { 13 $sql .= "AND name like :name "; 14 $params[':name'] = sprintf('%%%s%%', $name); 15} 16if ($category) { 17 $sql .= "AND category = :category "; 18 $params[':category'] = sprintf('%%%s%%', $category); 19} 20 21$stmt = $pdo->prepare($sql); 22$stmt->execute($params); 23 24var_dump($stmt->fetchAll()); 25

投稿2018/06/21 05:47

編集2018/06/21 06:02
退会済みユーザー

退会済みユーザー

総合スコア0

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

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

CheGuella

2018/06/21 06:10

ご教授ありがとうございます。仰る通り実務ではSQL1文でおこなうメリットは特になさそうですね。 1文で表現できたら楽かなと思った次第です。ありがとうございます。
退会済みユーザー

退会済みユーザー

2018/06/21 06:11

提示されたコード、SQLインジェクションの脆弱性あるけど、わかってて書いてますよね。一応。
CheGuella

2018/06/21 06:31

すいません、説明するためのコードだったのでサンプルでして!恐らく対応してます!ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.51%

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

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

質問する

関連した質問