1

コンマで区切られた州のリストを列に保存しています。

このように: 1,2,3,4,5,6,7,8.. など、ID だけです。

次に、ID 8 の状態を持つすべての行を取得するクエリを実行しています。これは、状態のリストに項目がほとんどない場合に機能します。

これはクエリとテーブルです。

mysql> select id_partner, name, states from partner where 8 IN (states);
+------------+----------------+--------------------+
| id_partner | name           | states             |
+------------+----------------+--------------------+
|          1 | Inmo Inmo      | 8,9,10             |
|          2 | Foto Piso      | 8,9,10,11,12,13,14 |
|          4 | PARTNER 001-A  | 8                  |
|          6 | EnAlquiler     | 8                  |
|          7 | Habitaclia.com | 8,43,50            |
+------------+----------------+--------------------+
5 rows in set (0.00 sec)

列の状態にコンマで区切られた 10 個の ID が含まれている場合は機能しますが、50 個以上の場合は機能しなくなります。上記の結果では、ID 8 を含む多くの状態を持つ行は表示されません。

何か案が?パートナーと状態の間の関係を保存するために別のテーブルを作成する必要がないために、このアプローチを使用していますか、それとももっとうまくやるべきですか?

4

2 に答える 2

1

文字列は単一の値であり、複数の値ではありません。たまたまコンマが含まれていますが、それでも単一の文字列です。

数値コンテキスト内の文字列の値は、先頭の数字から取得されます。つまり、'123,456,789' の数値は 123 です。MySQL は最初の非数字以降のすべての文字を無視します。(これは MySQL での動作であり、他のデータベースでは動作が異なる場合があります)。

IN( )述語を使用すると、複数の値を比較できますが、それらを個別の SQL 式にする必要があります。たとえば、次の 2 つのクエリでは、最初のクエリだけが何も返しません。

SELECT * FROM partner WHERE 5 IN ( 1, 2, 3, 4, 5 );

SELECT * FROM partner WHERE 5 IN ( '1,2,3,4,5' );

これは、コンマ区切りの要素を持つ文字列を使用して、実際には個別の値のコレクションであるかのように動作することを期待してはならない多くの理由の 1 つを示しています。

この場合のより良い設計は、特定のパートナーの状態を別のテーブルに格納することです。パートナーと状態の間の各関連付けは別の行にあります。

create table partner_states (
 id_partner int not null,
 id_state   int not null,
 primary key (id_partner, id_state)
);

次に入力します。

insert into partner_states (id_partner, id_state)
values (1, 8), (1, 9), (1, 10);

次に、特定の状態に一致するパートナーを簡単に照会できます。

select id_partner, name, states 
from partner p join partner_states s on p.id_partner = s.id_partner
where s.id_state = 8

外部結合で実行できる状態に一致しないパートナーのクエリ:

select id_partner, name, states 
from partner p left outer join partner_states s on p.id_partner = s.id_partner
  and s.id_state = 8
where s.id_state is null
于 2010-10-06T20:16:20.780 に答える
1

これは IN 句の仕組みではありません。FIND_IN_SET 関数を使用して、単一の列でカンマ区切りの値を検索する必要があります。

SELECT *  
  FROM partner 
 WHERE FIND_IN_SET(8, states) > 0

現実的には、カンマ区切りのデータを保存するべきではありません。これは非正規化データと呼ばれ、コンマ内の特定の値に関する情報を取得するのが難しい場合があります。

于 2010-10-06T20:11:02.750 に答える