2

'dealBusinessLocations'という名前のフィールド(テーブル'dp_deals'内)があり、コンマ区切り形式で別のテーブル(dp_business_locations)のIDが含まれています。

dealBusinessLocations
----------------------
0,20,21,22,23,24,25,26

クエリのin()関数内でこの値を使用する必要があります。

お気に入り

select * from dp_deals as d left join dp_business_locations as b on(b.businessLocID IN (d.dealBusinessLocations) ;

サインmysqlは文字列分解関数をサポートしていません。ストアド関数を作成しました

delimiter //
DROP FUNCTION IF EXISTS BusinessList;
create function BusinessList(BusinessIds text) returns text deterministic
BEGIN
  declare i int default 0;
  declare TmpBid text;
  declare result text default '';
  set TmpBid = BusinessIds;
  WHILE LENGTH(TmpBid) > 0 DO
           SET i = LOCATE(',', TmpBid);
           IF (i = 0)
                   THEN SET i = LENGTH(TmpBid) + 1;
           END IF;
           set result =  CONCAT(result,CONCAT('\'',SUBSTRING(TmpBid, 1, i - 1),'\'\,'));
           SET TmpBid =  SUBSTRING(TmpBid, i + 1, LENGTH(TmpBid));
  END WHILE;
  IF(LENGTH(result) > 0)
      THEN SET result = SUBSTRING(result,1,LENGTH(result)-1);
  END IF;
  return result;
END// 
delimiter  ;

関数は完全に機能しています。

mysql> BusinessList( '21,22' )
BusinessList( '21,22' )
-----------------------
'21','22'

ただし、関数を使用したクエリも機能しませんでした。これがクエリです。

select * from dp_deals as d left join dp_business_locations as b on(b.businessLocID IN (BusinessList(d.dealBusinessLocations)));

関数argumetに静的な値を使用してみましたが、使用できません

select * from dp_deals as d left join dp_business_locations as b on(b.businessLocID IN (BusinessList('21,22')));

関数から返された値の使用に問題があるようです。

4

3 に答える 3

3

まず、これを読んでください:

Is storing a comma separated list in a database column really that bad?
Yes, it is

次に、テーブルを正規化します。


さて、他の方法で本当にできない場合、または正規化するまで、次のFIND_IN_SET()関数を使用します。

select * 
from dp_deals as d 
  left join dp_business_locations as b 
    on FIND_IN_SET(b.businessLocID, d.dealBusinessLocations)

次に、その記事をもう一度読んでください。クエリが遅い場合、またはこのテーブルに他の問題がある場合は、次の理由がわかります。

Is storing a comma separated list in a database column really that bad?
Yes, it is

于 2011-12-01T12:50:03.030 に答える
2

シンプルで、find_in_set() 代わりに使用してください。

SELECT * 
FROM dp_deals as d 
LEFT JOIN dp_business_locations as b 
       ON (FIND_IN_SET(b.businessLocID,d.dealBusinessLocations) > 0); 

参照:http ://dev.mysql.com/doc/refman/5.0/en/string-functions.html#function_find-in-set

CSVを削除して地獄から抜け出す場合は、次のような単純な結合を使用できることに注意してください。

SELECT d.*, GROUP_CONCAT(b.dealBusinessLocation) as locations
FROM dp_deals as d 
LEFT JOIN dp_business_location as b 
       ON (d.dealBusinessLocation = b.businessLocID); 

これははるかに高速で、ボーナスとして正規化されます。

于 2011-12-01T12:48:21.933 に答える
0

あなたの問題は、IN()たくさんのフィールドを含む1つの文字列ではなく、たくさんのフィールドを取得することを期待していることだと思います。

あなたの関数であなたはそれにこれを送っています:

WHERE something IN ('\'21\',\'22\''); /* i.e. a single text containing "'21','22'" */

そして、期待されていません

WHERE something IN ('21','22');
于 2011-12-01T12:39:38.600 に答える