我有这个代码来搜索MYSQL数据库中的匹配结果:
$where[] = 'p.id IN (
SELECT adcfvc.advert_id
FROM #__koparent_advert_specific_fields_values AS adcfvc
WHERE adcfvc.advert_id = p.id
AND adcfvc.field_name = ' . $db->Quote($sf_key) . '
AND ' . $db->Quote(JString::strtolower($sf_value)) . ' = adcfvc.field_value
)';
我想更改上述搜索查询,使用等号“=”运算符选择完全匹配,使用带有两个通配符“%adcfvc.field_value%”的“LIKE”运算符选择任何匹配结果。
换句话说:上面代码的当前作用是当用户搜索“Hello my people”时,查询将搜索确切的单词。 但是,我希望用户能够仅使用“Hello”或“people”这个词进行搜索,并获得包括“Hello my people”在内的所有结果。
知道无论如何我都无法改变任何数据库结构,只需修改上面的代码即可。
名为“query.php”的整个代码文件位于: http://123dizajn.com/boltours/stackex/query.txt 我无法粘贴整个代码,因为它超出了体限,并且它被重命名为query.txt只是为了可见。
所以,我试图替换(在代码的最后):
= adcfvc.field_value
使用:
LIKE %adcfvc.field_value%
没有成功:(
我试图反转查找顺序并使用多个逻辑运算符: -
$where[] = 'p.id IN (
SELECT adcfvc.advert_id
FROM #__koparent_advert_specific_fields_values AS adcfvc
WHERE adcfvc.advert_id = p.id
AND adcfvc.field_name = ' . $db->Quote($sf_key) . '
AND
(adcfvc.field_value > ' . $db->Quote(JString::strtolower($sf_value)) . '
OR adcfvc.field_value < ' . $db->Quote(JString::strtolower($sf_value)) . '
OR adcfvc.field_value = ' . $db->Quote(JString::strtolower($sf_value)) . ')
)';
但是这会返回所有项目,而不是搜索到的项目!
我也试图反转并使用LIKE %...%
: -
$where[] = 'p.id IN (
SELECT adcfvc.advert_id
FROM #__koparent_advert_specific_fields_values AS adcfvc
WHERE adcfvc.advert_id = p.id
AND adcfvc.field_name = ' . $db->Quote($sf_key) . '
AND adcfvc.field_value LIKE %' . $db->Quote(JString::strtolower($sf_value)) . '%
)';
但这会返回错误:
1064您的SQL语法有错误;检查手册 对应于您的MySQL服务器版本,以便使用正确的语法 '%'公寓附近'%)GROUP BY p.id ORDER BY
ap
。price
DESC LIMIT 0, 第12行第20行SQL = SELECT p。,p.id AS id,p.title AS title, p.street_num,p.street,p.description as description,ap.price,pr.name 作为priceName,usr.id作为advert_user_id,countries.title作为 country_name,states.title as state_name,date_format(p.created, '%Y-%m-%d')为fcreated,c.title为category_title,c.id为category_id 来自b1yvu_koparent
ASp
LEFT JOINb1yvu_koparent_advert_prices
ASap
ON ap.advertId = p.id AND ap.advertDateRangeGroupId = 0 AND ap.priceId = p.priceUnitId LEFT JOINb1yvu_koparent_prices
ASpr
ON pr.id = p.priceUnitId LEFT JOINb1yvu_koparent_advertmid
ASpm
ON pm.advert_id = p.id LEFT JOINb1yvu_koparent_usermid
ASam
ON am.advert_id = p.id LEFT JOINb1yvu_koparent_users
ASusr
ON usr.id = am.user_id LEFT JOINb1yvu_koparent_categories
ASc
ON c.id = pm.cat_id LEFT JOINb1yvu_koparent_advert_specific_fields_values
ASasfv
ON asfv.advert_id = p.id LEFT JOINb1yvu_koparent_countries
AScountries
ON countries.id = p.country LEFT JOINb1yvu_koparent_states
ASstates
ON states.id = p.locstate WHERE p.published = 1 AND p.approved = 1 AND c.published = 1 AND (p.publish_up ='0000-00-00'OR p.publish_up&lt; ='2015-09-05')AND (p.publish_down ='0000-00-00'或p.publish_down&gt; ='2015-09-05')和 (c.publish_up ='0000-00-00'OR c.publish_up&lt; ='2015-09-05')和 (c.publish_down ='0000-00-00'OR c.publish_down&gt; ='2015-09-05')和 p.access IN(1,9)AND c.access IN(1,9)AND c.language IN ('en-GB','')和p.language IN('en-GB','*')AND p.id IN(SELECT adcfvc.advert_id FROM b1yvu_koparent_advert_specific_fields_values AS adcfvc WHERE adcfvc.advert_id = p.id AND adcfvc.field_name = 't4_cust_AdvertTitleEN'和adcfvc.field_value LIKE%'公寓'%) GROUP BY p.id ORDER BYap
。price
DESC LIMIT 0,20
任何帮助或建议表示赞赏。
答案 0 :(得分:2)
首先它是quote
而不是Quote
。
其次,您应该使用quoteName()
作为字段名称。
第三,没有理由因为你有子查询而停止使用API。
你的代码也很混乱,哪个是字段名称,哪个是值。我假设$sf_value
表示您要匹配的值,adcfvc.field
是存储您要匹配的数据的字段的名称。
替换
AND ' . $db->Quote(JString::strtolower($sf_value)) . ' = adcfvc.field_value
与
AND ' . $db->quoteName( 'adcfvc.field_value' ) . ' LIKE ' . $db->quote('%' . JString::strtolower($sf_value) . '%')
我不确定你为什么要在那里使用JString,但如果你认为有必要那么就好了。
这是你的子查询
SELECT adcfvc.advert_id
FROM #__koparent_advert_specific_fields_values AS adcfvc
WHERE adcfvc.advert_id = p.id
AND adcfvc.field_name = ' . $db->Quote($sf_key) . '
AND ' . $db->Quote(JString::strtolower($sf_value)) . ' = adcfvc.field_value
所以,因为你已经$db
了。
$subquery = $db->getQuery(true);
// Assuming p.id is an integer
$subquery->where($db->quoteName(adcfvc.advert_id) = p.id)
//Assuming $sf_key is an integer
->where($db->quoteName(adcfvc.field_name) . ' = ' . $sf_key)
->where($db->quoteName(adcfvc.field_value) . ' LIKE '
. $db->Quote('%'. JString::strtolower($sf_value) . '%')) ;
然后在顶级查询中,您刚刚向我们展示了一部分,例如
$query->where('p.id IN (' . $subquery . ')' );
答案 1 :(得分:0)
您可以使用concat
SELECT adcfvc.advert_id
FROM #__koparent_advert_specific_fields_values AS adcfvc
WHERE adcfvc.advert_id = p.id
AND adcfvc.field_name = ' . $db->Quote($sf_key) . '
AND 'Hello my people' like concat('%',adcfvc.field_value,'%')
order by adcfvc.field_value like '%Hello my people%' desc
这将匹配(Hello my people,Hello,my和people)添加顺序,以显示完全匹配
另一种方法,如果您可以使用您可以使用的字词或条件与field_value
SELECT adcfvc.advert_id
FROM #__koparent_advert_specific_fields_values AS adcfvc
WHERE adcfvc.advert_id = p.id
AND adcfvc.field_name = ' . $db->Quote($sf_key) . '
AND (
adcfvc.field_value like '%Hello my people%'
or adcfvc.field_value like '%Hello%'
or adcfvc.field_value like '%my%'
or adcfvc.field_value like '%people%'
)
order by adcfvc.field_value like '%Hello my people%' desc
答案 2 :(得分:0)
使用RLIKE
代替接近的LIKE
是我问题的最简单直接的解决方案。
最终完整查询: -
$where[] = 'p.id IN (
SELECT adcfvc.advert_id
FROM #__koparent_advert_specific_fields_values AS adcfvc
WHERE adcfvc.advert_id = p.id
AND adcfvc.field_name = ' . $db->Quote($sf_key) . '
AND adcfvc.field_value RLIKE ' . $db->Quote(JString::strtolower($sf_value)) . '
)';
这会使结果返回其名称包含所搜索的值的所有项目。