2012-02-08 18 views
0

私は1人のユーザーが自分の友達のいずれかのユーザーIDを招待者の列に入れることを許可するグループ機能を自分のウェブサイトに持っています。私は、ログインしたユーザーのIDが、自分の友達によってinvitedusers列に格納されているかどうかを判別するためにSQL検索を行う必要があります。 SQL検索でこれを行うにはどうすればよいですか?SQL配列の検索

EX:私の列はinvitedusersで、その列の中には次のように格納されています(234,394,479) Userid 234がログインしている場合、invitedusers列に格納されているuserid 234がある列を検索する必要があります。

SELECT userid, name... FROM mytable WHERE invitedusers = ? 

*私はFIND_IN_SETと一緒にSQLのIN演算子を見ていないが、どちらかと何の助け*

+0

私はあなたが「好き」を探していると思います。 '%234% '' –

+0

のような招待された人たちからのmytableからの私はあなたがテーブルスキーマの例なしであなたを助けることができないのです。 – Vyktor

+1

なぜ人々は、きちんと正規化されたテーブルを最初に設計するのではなく、悪いデータベース設計を回避する方法を見つけるのが常に苦労していますか? –

答えて

2

実際に234,394,479を1列の値として使用しているとします(少なくとも,234,394,479,を使用してを実行する必要があります)。クエリで)あなたは、自分のユーザーテーブルを再構築フィールドinvited_usersを削除して、このような表を作成する必要があります

CREATE TABLE invited_users (
    id INT AUTO_INCREMENT, 
    owner_id INT, -- Who's input it is 
    target_id INT, -- What's the target user 
    PRIMARY KEY (id), 
    UNIQUE (owner_id, target_id), 
    -- Indexes (FOREIGN KEYs!) to users table 
); 

とクエリをユーザー234に招待されたユーザだけの選択リストより:

SELECT users.id, users.name 
FROM invited_users 
INNER JOIN users ON invited_users.owner_id = users.id 
GROUP BY users.id 
WHERE invited_users.target_id = 234 
+0

このVyktorに感謝します。間違いなくそれを実装する。 – user1011713

1

あなたが列にカンマ区切りのリストを保存したくないかもしれないが、あなたがあるので、:。

SELECT userid, name FROM mytable 
WHERE invitedusers = '(' + '234' + ')' -- One and only one entry 
OR invitedusers LIKE '(' + '234' + ',%' -- First entry 
OR invitedusers LIKE '%,' + '234' + ',%' -- Middle entry 
OR invitedusers LIKE '%,' + '234' + ')%' -- Last entry 

私はEBarrのコメントに基づいて修正しました。確認するケースは4つあります。これは、データに接頭辞(接頭辞とa)を付けて保存し、すべてをカンマで区切っていることを前提としています。ここで

は、それが動作することを証明するためにいくつかのテストです:

/* Tests */ 
INSERT INTO @mytable SELECT 11, 'a', '(234)' -- Should get returned 
INSERT INTO @mytable SELECT 12, 'b', '(1234)' 
INSERT INTO @mytable SELECT 13, 'c', '(92349)' 
INSERT INTO @mytable SELECT 13, 'd', '(2345)' 

INSERT INTO @mytable SELECT 21, 'a', '(234,567)' -- Should get returned 
INSERT INTO @mytable SELECT 22, 'b', '(1234,567)' 
INSERT INTO @mytable SELECT 23, 'c', '(92349,567)' 
INSERT INTO @mytable SELECT 23, 'd', '(2345,567)' 

INSERT INTO @mytable SELECT 31, 'a', '(567,234)' -- Should get returned 
INSERT INTO @mytable SELECT 32, 'b', '(567,1234)' 
INSERT INTO @mytable SELECT 33, 'c', '(567,92349)' 
INSERT INTO @mytable SELECT 33, 'd', '(567,2345)' 

INSERT INTO @mytable SELECT 41, 'a', '(123,234,789)' -- Should get returned 
INSERT INTO @mytable SELECT 42, 'b', '(123,1234,789)' 
INSERT INTO @mytable SELECT 43, 'c', '(123,92349,789)' 
INSERT INTO @mytable SELECT 43, 'd', '(123,2345,789)' 

SELECT userid, name FROM @mytable 
WHERE invitedusers = '(' + '234' + ')' -- One and only one entry 
OR invitedusers LIKE '(' + '234' + ',%' -- First entry 
OR invitedusers LIKE '%,' + '234' + ',%' -- Middle entry 
OR invitedusers LIKE '%,' + '234' + ')%' -- Last entry 
+0

ああ、私は彼が昏睡区切り文字列として格納されているIDを持っていないことを願って... – Vyktor

+4

あなたのLIKE基準に区切り文字を追加する必要があります。あなたが書いたように、234、1234、92349、および2345 – EBarr

+0

こんにちはスティーブンのエントリに一致します。カンマ区切りリストのより良い解決策は何でしょうか? – user1011713

0

私はこれが最善の方法が、あるかどうかわからないんだけど:

where concat(',',invitedusers,',') like '%,234,%' 

だからあなたの例では,234,,234,394,479,

の内側にあります
1

これを

SELECT userid, name... FROM mytable WHERE FIND_IN_SET('234', invitedusers) !=0;