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)));

我也尝试过对函数参数使用静态值,但没用

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()不希望得到一个包含很多字段的字符串,而是很多字段。

使用您的功能,您将发送它:

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

而不是预期的

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