web-dev-qa-db-ja.com

複数の条件を持つMySQLの選択クエリ

MySQLクエリを作成しましたが、結果が空であるため、機能していないようです。私のコードに間違いはありますか?

$result = mysql_query(
     "SELECT user_id 
      FROM wp_usermeta 
      WHERE 
         (meta_key = 'first_name' AND meta_value = '$us_name') AND         
         (meta_key = 'yearofpassing' AND meta_value = '$us_yearselect') AND 
         (meta_key = 'u_city' AND meta_value = '$us_reg') AND 
         (meta_key = 'us_course' AND meta_value = '$us_course')"
);
40

私はこのクエリを使用します:

SELECT
  user_id
FROM
  wp_usermeta 
WHERE 
  (meta_key = 'first_name' AND meta_value = '$us_name') OR 
  (meta_key = 'yearofpassing' AND meta_value = '$us_yearselect') OR 
  (meta_key = 'u_city' AND meta_value = '$us_reg') OR
  (meta_key = 'us_course' AND meta_value = '$us_course')
GROUP BY
  user_id
HAVING
  COUNT(DISTINCT meta_key)=4

これにより、4つの条件すべてを満たすuser_idがすべて選択されます。

46
fthiella

@fthiellaのソリューションは非常にエレガントです。

将来的にuser_id以上を表示したい場合は、結合を使用できます。また、1行で必要なすべてのデータを表示できます。

AND条件を使用する場合、条件がテーブル内の複数行にある場合、JOINSの例を使用できます。

SELECT `w_name`.`user_id` 
     FROM `wp_usermeta` as `w_name`
     JOIN `wp_usermeta` as `w_year` ON `w_name`.`user_id`=`w_year`.`user_id` 
          AND `w_name`.`meta_key` = 'first_name' 
          AND `w_year`.`meta_key` = 'yearofpassing' 
     JOIN `wp_usermeta` as `w_city` ON `w_name`.`user_id`=`w_city`.user_id 
          AND `w_city`.`meta_key` = 'u_city'
     JOIN `wp_usermeta` as `w_course` ON `w_name`.`user_id`=`w_course`.`user_id` 
          AND `w_course`.`meta_key` = 'us_course'
     WHERE 
         `w_name`.`meta_value` = '$us_name' AND         
         `w_year`.meta_value   = '$us_yearselect' AND 
         `w_city`.`meta_value` = '$us_reg' AND 
         `w_course`.`meta_value` = '$us_course'

その他:mysql_*関数はSQLインジェクションの保存ではなく、廃止されるため、準備済みステートメントを使用することをお勧めします。できるだけコードを変更したくない場合は、mysqli_関数を使用できます。 http://php.net/manual/en/book.mysqli.php

勧告:

このテーブルでインデックスを使用します。 user_idは、インデックスを作成することを強くお勧めします。クエリの実行を高速化するために、meta_key AND meta_valueも使用することをお勧めします。

Explain:

ANDを使用すると、1行の条件を「接続」します。したがって、複数行のAND条件が必要な場合は、最初に次のように複数行から1行を作成する必要があります。

テスト:テーブルデータ:

          PRIMARY                 INDEX
      int       varchar(255)    varchar(255)
       /                \           |
  +---------+---------------+-----------+
  | user_id | meta_key      | meta_value|
  +---------+---------------+-----------+
  | 1       | first_name    | Kovge     |
  +---------+---------------+-----------+
  | 1       | yearofpassing | 2012      |
  +---------+---------------+-----------+
  | 1       | u_city        | GaPa      |
  +---------+---------------+-----------+
  | 1       | us_course     | PHP       |
  +---------+---------------+-----------+

$us_name='Kovge'$us_yearselect='2012'$us_reg='GaPa'$us_course='PHP'を使用したクエリの結果:

 +---------+
 | user_id |
 +---------+
 | 1       |
 +---------+

動作するはずです。

25
Kovge

また、両方の属性を適用する場合は、「OR」の代わりに「AND」を使用できます。

select * from tickets where (assigned_to='1') and (status='open') order by created_at desc;
3
Adam Falchetta