MySQL WHERE IN()


84

私の質問は:

SELECT * FROM table WHERE id IN (1,2,3,4);

私はこれをユーザーグループに使用しており、ユーザーは複数のグループに属することができます。しかし、レコードに1や3のような複数のIDがある場合、mySQLはその行を返さないようです。

その行を取得する方法もありますか?


7
このクエリから適切に返されない行の例を投稿してください。をidコンマ区切りのリストなどとして保存していないとすると、クエリから複数の行返されます。
Michael Berkowski 2012年

1
それはコンマで区切られたリストです。たとえば、=> 3,4はmySQLによって返されません。問題が発生しました。コンマに関するものですが、どうすればよいですか?
ネットケース2012年

1
@ user762683、適切なプロファイル名を使用してください?そして、this id、varchar、set、enumのデータ型は何ですか?
Starx 2012年

1
@Starx誰かが使用するプロファイル名はあなたのどのビジネスですか?
Michael Berkowski 2012年

1
@Michaelは、ようOPに対応するような音がいかに簡単か、正しい参照netcaseの代わりに@user762683
Starx 2012年

回答:


82

クエリは次のように変換されます

SELECT * FROM table WHERE id='1' or id='2' or id='3' or id='4';

それに一致する結果のみが返されます。


複雑さを回避してそれを解決する1つの方法は、データ型をに変更することSETです。次に、FIND_IN_SETを使用できます

SELECT * FROM table WHERE FIND_IN_SET('1', id);

エラーを再現することはできません。要求されたクエリは私のために働きます。リストされたIDを持つ「テーブル」からすべてのレコードを取得します。
BF

39

データベースの設計が間違っているため、データベースの正規化について何かを読む必要があります(wikipedia / stackoverflow)。

私はあなたのテーブルがこのように見えると思います

TABLE
================================
| group_id | user_ids | name   |
--------------------------------
| 1        | 1,4,6    | group1 |
--------------------------------
| 2        | 4,5,1    | group2 |    

したがって、ユーザーグループのテーブルでは、各行が1つのグループを表し、user_ids列にはそのグループに割り当てられたユーザーIDのセットがあります。

このテーブルの正規化されたバージョンは次のようになります

GROUP
=====================
| id       | name   |
---------------------
| 1        | group1 |
---------------------
| 2        | group2 |    

GROUP_USER_ASSIGNMENT
======================
| group_id | user_id |
----------------------
| 1        | 1       |
----------------------
| 1        | 4       |
----------------------
| 1        | 6       |
----------------------
| 2        | 4       |
----------------------
| ...      

次に、グループが割り当てられているすべてのユーザー、グループ内のすべてのユーザー、ユーザーのすべてのグループ、または考えられるあらゆるものを簡単に選択できます。また、SQLクエリは機能します。

/* Your query to select assignments */
SELECT * FROM `group_user_assignment` WHERE user_id IN (1,2,3,4);

/* Select only some users */
SELECT * FROM `group_user_assignment` t1
JOIN `group` t2 ON t2.id = t1.group_id
WHERE user_id IN (1,4);

/* Select all groups of user */
SELECT * FROM `group_user_assignment` t1
JOIN `group` t2 ON t2.id = t1.group_id
WHERE t1.`user_id` = 1;

/* Select all users of group */
SELECT * FROM `group_user_assignment` t1
JOIN `group` t2 ON t2.id = t1.group_id
WHERE t1.`group_id` = 1;

/* Count number of groups user is in */
SELECT COUNT(*) AS `groups_count` FROM `group_user_assignment` WHERE `user_id` = 1;

/* Count number of users in group */
SELECT COUNT(*) AS `users_count` FROM `group_user_assignment` WHERE `group_id` = 1;

このようにして、データベースの更新も簡単になります。新しい割り当てを追加するgroup_user_assignment場合は、に新しい行を挿入するだけですgroup_user_assignment。割り当てを削除する場合は、の行を削除するだけです。

データベース設計では、割り当てを更新するには、データベースから割り当てセットを取得し、それを処理して更新してから、データベースに書き戻す必要があります。

これがsqlFiddleで遊ぶことです。


1

テーブルにレコードがあるか、データベースに配列レコードが必要です。

例:

SELECT * FROM tabel_record
WHERE table_record.fieldName IN (SELECT fieldName FROM table_reference);

副選択は必要ありません。IN (1,2,3,4)完全に有効です。また、これが質問の「レコードに1と3のような複数のIDがある場合、mySQLはその行を返さない」とどのように説明するのかわかりません。
scratte
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.