0

我有以下复杂的 SQL 语句,它使用“IN”来搜索多个类别。

SELECT MATCH(placename,fullloc) AGAINST ('' IN BOOLEAN MODE) as score, places.PlaceName, places.fullloc, places.PlaceID, places.ImageThumb, places.contributorid, places.verified, places.verified_by, places.verified_date, places.visibility 
FROM places 
INNER JOIN places_cats ON places.PlaceID = places_cats.PlaceID 
WHERE STATUS IN (1,0) 
  AND places_cats.CATID in (129,75,104) 
  AND (visibility = 1 OR (visibility in (2,3) 
  AND places.contributorid = '999999999'))
GROUP BY PlaceID 
ORDER BY score DESC

我希望能够将它从一个“IN”切换,这基本上使它成为一个多重“OR”语句,它会给我一个多重“AND”语句。是否有一个简单的 SQL 命令可以让我这样做,还是我必须实际创建一个多重“AND”语句?

CATID 列表可能会变得很长。事实上,有时猫列表是 35 项。

4

1 回答 1

0

IN将一行中的一个值与列表进行比较。您要求的是完全不同的:查找列表中的每个值是否存在单独的行。你不能用一个简单的运算符来做到这一点。(如果你真的有一个AND,你不会得到任何行回来,因为相同的值不能同时等于 129 和 75。)

对于您想要的每个类别,您必须加入一次或子查询一次。

SELECT ...
FROM places
INNER JOIN places_cats pc1 ON places.PlaceID = pc1.PlaceID AND pc1.CATID = 129
INNER JOIN places_cats pc2 ON places.PlaceID = pc2.PlaceID AND pc2.CATID = 75
INNER JOIN places_cats pc3 ON places.PlaceID = pc3.PlaceID AND pc3.CATID = 104

或者:

SELECT ...
FROM places
WHERE places.PlaceID IN (SELECT PlaceID FROM places_cats WHERE CATID = 129)
AND places.PlaceID IN (SELECT PlaceID FROM places_cats WHERE CATID = 75)
AND places.PlaceID IN (SELECT PlaceID FROM places_cats WHERE CATID = 104)

或者:

SELECT ...
FROM places
WHERE EXISTS (SELECT * FROM places_cats WHERE places_cats.PlaceID = places.PlaceID AND CATID = 129)
AND EXISTS (SELECT * FROM places_cats WHERE places_cats.PlaceID = places.PlaceID AND CATID = 75)
AND EXISTS (SELECT * FROM places_cats WHERE places_cats.PlaceID = places.PlaceID AND CATID = 194)

哪一个更容易生成(并且运行效率最高)取决于您的代码和 MySQL 的特性。

于 2013-11-06T21:09:11.690 回答