2

MySQLに2つのテーブルがあります

表 1: ID のリスト

-- ID の 1 列のリストのみ

表 2: グループ

--グループタイトル

-- メンバー **

現在、メンバー フィールドは基本的に、そのグループの一部であるすべての ID がリストされているコメント フィールドです。たとえば、メンバーの 1 つのフィールド全体は次のようになります。

"ID003|ID004|ID005|ID006|ID007|ID008|... Etc."

そこには、フィールドに最大 500 以上のリストが表示されます。

私がやりたいことは、クエリを実行して、どの ID が 3 つ以下のグループにのみ表示されるかを調べることです。

私はそれにひびを入れてきましたが、正直なところ、私は完全に迷っています。何か案は?

4

2 に答える 2

4

編集; 初めて質問を誤解したので、答えを変更します。

SELECT l.id
FROM List_of_ids AS l
JOIN Groups AS g ON CONCAT('|', g.members, '|') LIKE CONCAT('%|', l.id, '|%')
GROUP BY l.id
HAVING COUNT(*) <= 3 

これは、両方のテーブルのテーブルスキャンを強制するため、パフォーマンスが非常に悪くなります。500 個の ID と 500 個のグループがある場合、250000 回の比較を実行する必要があります。

シンボルで区切られたリストを保存することがこれを行う正しい方法であるかどうかを本当に検討する必要があります。データベース列に区切られたリストを格納するのは本当に悪いですか?への私の回答を参照してください。

このような関係を設計する適切な方法は、ID をグループにマップする 3 番目のテーブルを作成することです。

CREATE TABLE GroupsIds (
  memberid INT,
  groupid INT,
  PRIMARY KEY (memberid, groupid)
);

このテーブルでは、結合にインデックスを使用することで、はるかに効率的になります。

SELECT l.id
FROM List_of_ids AS l
JOIN GroupsIds AS gi ON gi.memberid = l.id
GROUP BY l.id
HAVING COUNT(*) <= 3 
于 2013-10-21T21:24:22.250 に答える
2
select * from
(
    select ID,
    (
        select count(*)
        From Groups
        where LOCATE(concat('ID', a.id, '|'), concat(Members, '|'))>0
    ) as groupcount
    from ListIDTable as a
) as q
where groupcount <= 3
于 2013-10-21T21:27:34.290 に答える