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

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

ただいまの
回答率

90.49%

  • MySQL

    7110questions

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

  • PDO

    389questions

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

MYSQLで複数パターンの条件がある場合の、selectの方法

解決済

回答 4

投稿 編集

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

SugiuraY

score 208

いつもお世話になります。
下記のように、A社及びB社を軸に複数の条件に応じてselectして
該当する値をDBから取得したい(該当があるとは限らない)のですが、
自分の知識では、提示のコードのようにfor文でループさせるしか思いつきません。
もちろん、このようにするとクエリを何度も発行するので非常に重い処理になってしまいます。
何か良い方法はございますでしょうか?

$array_1=array(array("A社",100),array("A社",200),array("B社",300));
$array_2=array("aaaa","bbbb");

for ($i=0; $i <count($array_1); $i++) { 
    for ($j=0; $j <count($array_2); $j++) { 

try {
//一部省略
$sql=$pdo->query("SELECT B FROM testDB where C=:one AND D=:two AND E=:three");
$stmt=$pdo->prepare($sql);
$stmt->bindValue(':one',$array_1[$i][0] , PDO::PARAM_STR);
$stmt->bindValue(':two',$array_1[$i][1] , PDO::PARAM_STR);
$stmt->bindValue(':three',$array_2[$i], PDO::PARAM_STR);
$stmt->execute();
$result=$stmt->fetchall(PDO::FETCH_NUM);
} catch (Exception $e) {
var_dump($e->getMessage());
}


  }
}

//期待するresult
//1) A社/100/aaaaの組み合わせ→1000
//2) A社/200/bbbbの組み合わせ→3000
//3) B社/300/bbbbの組み合わせ→4000


>>testDB
[A] [B] [C] [D][ E]
1,1000,A社,100,aaaa
2,2000,A社,200,zzzz
3,3000,A社,200,bbbb
4,4000,B社,300,bbbb
5,5000,B社,300,zzzz
6,4000,B社,100,yyyy
7,3000,C社,500,kkkk
8,2000,C社,300,aaaa
9,1000,C社400,dddd
  • 気になる質問をクリップする

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 4

checkベストアンサー

+2

PHPは詳しくないのですが、SQLでは以下のような問い合わせが可能です。

SELECT B FROM testDB 
where (C, D, E) In (
        ('A社',100,'aaaa'),('A社',200,'bbbb'),('B社',300,'bbbb') -- この部分を動的に生成
      )


同じループで回すにしても、上記の配列部分を動的に生成すれば、SQLの発行も1度で済みます。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2017/10/13 18:44

    コメント有難うございます。
    where inを初めて知りました!
    早速使ってみます!

    キャンセル

  • 2017/10/13 18:44

    コメント有難うございます。
    where inを初めて知りました。
    早速使ってみます!

    キャンセル

+2

たとえばこう

$a1=[["A社",100],["A社",200],["B社",300]];
$a2=["aaaa","bbbb"];
$a3=[];
$sql="select * from tbl where 1 \n";
$sql.="AND ( 0 \nOR ";
$sql.=implode ("OR ",array_fill(0,count($a1)*count($a2),"C=? AND d=? AND E=? \n"));
$sql.=") " ;
print $sql;
$a3=[];
foreach($a1 as $ax){
  foreach($a2 as $val){
    $a3=array_merge($a3,$ax);
    array_push($a3,$val);
  }
}
print_r($a3);
/*
$stmt=$pdo->prepare($sql);
$stmt->execute($a3);
*/

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2017/10/14 02:05

    yambejp様
    いつもコメントありがとうございます。
    何点か使い方がわからないものについて、調べてみました。
    1) where 1 は無条件で全データを返しのちの条件を書きやすくすることができるのですね。初めて知りました。ありがとうございます。
    2) 一方2点調べてもわからなかったのですが、”0 OR”の0が意味するところと”\n”で改行を入れている点です。何か参考になるサイトだけでもとても嬉しいです。
    よろしくお願い申し上げます。

    キャンセル

0

ちょっと雑に書きましたが、"aaaa"と"bbbb"を抽出してからループしても良いかもしれません。

<?php
ini_set('display_errors', true);
error_reporting(E_ALL);

$dsn = 'mysql:host=localhost;dbname=test;charset=utf8;';
$username = 'test';
$password = 'test';
$options = [
    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
    , PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC
];
$oPdo = new PDO($dsn, $username, $password, $options);
$array_1=array(array("A社","100"),array("A社","200"),array("B社","300"));
$array_2=array("aaaa","bbbb");
$inClause = substr(str_repeat(',?', count($array_2)), 1);
$sql = "SELECT B,C,D FROM testDB where  E in (%s)";
$stmt = $oPdo->prepare(sprintf($sql, $inClause));
$stmt->execute($array_2);
$result=$stmt->fetchall(PDO::FETCH_NUM);
foreach ($result as $value) {
    foreach ($array_1 as $searchVal) {
        if($value[1] === $searchVal[0] and $value[2] === $searchVal[1]){
            echo $value[0].$value[1].$value[2].nl2br("\n");
        }
    }
}
?>

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2017/10/13 18:43

    コメント有難うございます。ちょっとphp的にわからない部分もあったので勉強してみます!

    キャンセル

0

単純にSQLでだけ考えると、

SELECT B FROM testDB where
(
  (C='A社' AND D=100 AND E='aaaa') OR
  (C='B社' AND D=200 AND E='bbbb') OR
  (C='B社' AND D=300 AND E='bbbb')
)


という形になります。
なので、上のような SQL を動的に作成してみましょう。

$wheres = array();
foreach($array1 as $company) {
  foreach($array2 as $code) {
    $wheres[] = sprintf("C='%s' AND D=%s AND E='%s')", $company[0], $company[1], $code);
  }
}
$sql = "SELECT B FROM testDB WHERE (" . implode(" OR ", $wheres) . ")";
...


でどうでしょうか。 

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2017/10/13 18:41

    有難うございます。
    大変参考になりました!

    キャンセル

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

  • MySQL

    7110questions

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

  • PDO

    389questions

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