0

データを複数のテーブルに正規化する代わりに、テーブル列に区切りリストを使用することがいかに悪いことか十分に認識しています。

ただし、数年前に設計されたテーブル構造があり、すぐに再設計します。
簡略化すると、次のようになります。

Table: Newsletters
+------------+---------------+
| subject    | mailing_lists |
+------------+---------------+
| A Test     | 1,2           |
| More Tests | 2,3           |
+------------+---------------+ 

必要に応じて、このSQLFiddleで確認できます。

最近、ビューに表示するニュースレターを選択する機能として、メーリング リスト ID (1,3 など)の区切りリストを作成するオプションをユーザーに提供しました。
(例: ID 1 または 3 のリストに送信されたニュースレターのみを表示する)

つまり、ID の区切られたリストと、区切られた ID を入力として含むテーブル列。

テーブルが正規化されていれば、これは明らかにはるかに簡単になります。

そこで、PHP でこれを解決しました。入力 ID を展開し、それらを繰り返し処理して、上記のフィドルのようなクエリを作成しました。これは次のようになります。

SELECT * FROM `newsletters`
  WHERE FIND_IN_SET("1", `mailing_lists`) > 0
     OR FIND_IN_SET("3", `mailing_lists`) > 0

このクエリは、取得したいデータを完全にフェッチしますが、区切られたリストの各 ID に新しい条件を追加する必要があるため、プログラムでしか作成できません。

質問:純粋な好奇心から: PHP でループを回避し、コードで ID を分割せずにクエリを作成する方法はありますか?

4

2 に答える 2

1

による非常に有用な投稿の後rakeshjain、クエリを次のように変換することができました。

SELECT * FROM (SELECT *,
               `mailing_lists` REGEXP REPLACE("1,3", ',', '(\\,|$)|')
                  as haslists
               FROM `newsletters` B) A
  WHERE A.haslists = 1

上記では、「1,3」がユーザーから提供された値であると想定しています。
これが解決されたフィドルです:http://sqlfiddle.com/#!2/4621b0/19

ありがとうrakeshjain

于 2013-10-14T07:27:04.447 に答える
0

はい、ループを回避する方法があります。データベース構造を正規化するだけです。

テーブル「サブジェクト」 subjectID (INT(11), auto_increment) | 件名 (varchar(255))

テーブル "MailingLists" listID (INT(11), auto_increment) | リスト名

テーブル "Subjects2Lists" (多対多) subjectID (インデックス) | listID (インデックス)

したがって、単純な select / join ステートメントを実行するだけで、すべてのリスト ID を取得できます。

SELECT 
    list.listID, 
    names.listName 
FROM 
    Subject2Lists AS list 
LEFT JOIN 
    MailingLists AS names 
    ON (list.listID = names.listID) 
WHERE 
    subjectID = 1 
于 2013-10-14T06:21:52.493 に答える