将多条查询结果作为like查询条件
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了将多条查询结果作为like查询条件相关的知识,希望对你有一定的参考价值。
有表X,Y
select id from X where c
Y中a字段为包含有X中id字段的字符串,
现在如何将所有满足条件c的id和Y中的a字段进行匹配
大概是这样 select * from Y where a like '%(select id from X where c)%' 这个语句是错误的。请教高手该如何处理。
select id from X where c结果为多个结果
SQL> select * from t1;
ID1 ID2 ID3
---------- ---------- ----------
12it1 ababcda a^a
a12it1 ababcdad a^^a
ba12it1 ababcd1ad a^&^a
it1 ababcd a^^
ba12it abcd1ad a^&^
SQL> select * from t2;
ID1 ID2 ID3
---------- ---------- ----------
it aabcd1 a^a
it abcd ^
i abcd1 ^a
SQL> select t1.* from t1,t2 where t1.id1 like '%'||t2.id1||'%';
ID1 ID2 ID3
---------- ---------- ----------
12it1 ababcda a^a
12it1 ababcda a^a
12it1 ababcda a^a
a12it1 ababcdad a^^a
a12it1 ababcdad a^^a
a12it1 ababcdad a^^a
ba12it1 ababcd1ad a^&^a
ba12it1 ababcd1ad a^&^a
ba12it1 ababcd1ad a^&^a
it1 ababcd a^^
it1 ababcd a^^
ID1 ID2 ID3
---------- ---------- ----------
it1 ababcd a^^
ba12it abcd1ad a^&^
ba12it abcd1ad a^&^
ba12it abcd1ad a^&^
已选择15行。
SQL> 参考技术B select A.* from Y A,X B
where A.a like '%B.id%' 参考技术C oracle:
select y.*
from X x,Y y
where y.a like '%'||x.id||'%'
sqlserver:
select y.*
from X x,Y y
where y.a like '%'+x.id+'%'
PHP/MySQL:突出显示“SOUNDS LIKE”查询结果
【中文标题】PHP/MySQL:突出显示“SOUNDS LIKE”查询结果【英文标题】:PHP/MySQL: Highlight "SOUNDS LIKE" query results 【发布时间】:2010-12-19 04:38:13 【问题描述】:快速 MYSQL/PHP 问题。如果使用普通搜索查询未找到任何结果,我将使用“不那么严格”的搜索查询作为后备,以达到以下目的:
foreach($find_array as $word)
clauses[] = "(firstname SOUNDS LIKE '$word%' OR lastname SOUNDS LIKE '$word%')";
if (!empty($clauses)) $filter='('.implode(' AND ', $clauses).')';
$query = "SELECT * FROM table WHERE $filter";
现在,我使用 PHP 来突出显示结果,例如:
foreach ($find_array as $term_to_highlight)
foreach ($result as $key => $result_string)
$result[$key]=highlight_stuff($result_string, $term_to_highlight);
但是当我不知道要突出显示什么时,这种方法就会失败。有什么方法可以在运行 mysql 查询时找出“声音相似”匹配是什么?
也就是说,如果有人搜索“Joan”,我希望它改为突出显示“John”。
【问题讨论】:
也许查询 SELECT * FROM table WHERE $clauses 是 SELECT * FROM table WHERE $filter? 呃,是的——很抱歉。我试图简化我手头的脚本的可怕混乱,但它却从我身边溜走了。 【参考方案1】:SOUND LIKE 条件只是比较两个单词的 SOUNDEX 键,您可以使用 PHP soundex() 函数生成相同的键。
因此,如果您找到匹配的行并需要找出要突出显示的单词,则可以同时获取名字和姓氏,然后使用 PHP 查找匹配的行并仅突出显示该单词。
我编写此代码只是为了尝试一下。 (必须测试我的理论 xD)
<?php
// A space seperated string of keywords, presumably from a search box somewhere.
$search_string = 'John Doe';
// Create a data array to contain the keywords and their matches.
// Keywords are grouped by their soundex keys.
$data = array();
foreach(explode(' ', $search_string) as $_word)
$data[soundex($_word)]['keywords'][] = $_word;
// Execute a query to find all rows matching the soundex keys for the words.
$soundex_list = "'". implode("','", array_keys($data)) ."'";
$sql = "SELECT id, firstname, lastname
FROM sounds_like
WHERE SOUNDEX(firstname) IN($soundex_list)
OR SOUNDEX(lastname) IN($soundex_list)";
$sql_result = $dbLink->query($sql);
// Add the matches to their respective soundex key in the data array.
// This checks which word matched, the first or last name, and tags
// that word as the match so it can be highlighted later.
if($sql_result)
while($_row = $sql_result->fetch_assoc())
foreach($data as $_soundex => &$_elem)
if(soundex($_row['firstname']) == $_soundex)
$_row['matches'] = 'firstname';
$_elem['matches'][] = $_row;
else if(soundex($_row['lastname']) == $_soundex)
$_row['matches'] = 'lastname';
$_elem['matches'][] = $_row;
// Print the results as a simple text list.
header('content-type: text/plain');
echo "-- Possible results --\n";
foreach($data as $_group)
// Print the keywords for this group's soundex key.
$keyword_list = "'". implode("', '", $_group['keywords']) ."'";
echo "For keywords: $keyword_list\n";
// Print all the matches for this group, if any.
if(isset($_group['matches']) && count($_group['matches']) > 0)
foreach($_group['matches'] as $_match)
// Highlight the matching word by encapsulatin it in dashes.
if($_match['matches'] == 'firstname')
$_match['firstname'] = "-$_match['firstname']-";
else
$_match['lastname'] = "-$_match['lastname']-";
echo " #$_match['id']: $_match['firstname'] $_match['lastname']\n";
else
echo " No matches.\n";
?>
一个更通用的函数,从字符串中提取匹配的 soundex 单词可能如下所示:
<?php
/**
* Attempts to find the first word in the $heystack that is a soundex
* match for the $needle.
*/
function find_soundex_match($heystack, $needle)
$words = explode(' ', $heystack);
$needle_soundex = soundex($needle);
foreach($words as $_word)
if(soundex($_word) == $needle_soundex)
return $_word;
return false;
?>
如果我理解正确,可以在您之前发布的代码中使用:
foreach ($find_array as $term_to_highlight)
foreach ($result as $key => $result_string)
$match_to_highlight = find_soundex_match($result_string, $term_to_highlight);
$result[$key]=highlight_stuff($result_string, $match_to_highlight);
这不会像第一个 sn-p 中更有针对性的代码那样有效。
【讨论】:
【参考方案2】:请注意,SOUNDS LIKE
并不像您想象的那样工作。它不等同于 MySQL 中的LIKE
,因为它不支持%
通配符。
这意味着在搜索“John”时,您的查询不会找到“John David”。如果这只是您的后备方案,这可能是可以接受的,但这并不理想。
所以这里有一个不同的建议(可能需要改进);首先使用 PHPs soundex()
函数找到您要查找的关键字的 soundex。
$soundex = soundex($word);
$soundexPrefix = substr($soundex, 0, 2); // first two characters of soundex
$sql = "SELECT lastname, firstname ".
"FROM table WHERE SOUNDEX(lastname) LIKE '$soundexPrefix%' ".
"OR SOUNDEX(firstname) LIKE '$soundexPrefix%'";
现在您将获得一个名字和姓氏的列表,这些名字和姓氏在发音上具有模糊的相似性(这可能是很多条目,您可能希望增加用于搜索的 soundex 前缀的长度)。然后,您可以计算每个单词的 soundex 与您的搜索词之间的 Levenshtein 距离,并按此排序。
其次,你应该看看 MySQL 中的参数化查询,以避免 SQL 注入错误。
【讨论】:
感谢您指出这一点。不过,在我的情况下,“John”确实匹配“John David”。我将查询分解为单词,并根据我搜索的每个字段检查每个单词。如,如果搜索字符串是“John David”,则“WHERE(姓氏听起来像'John'或名字听起来像'John')和(姓氏听起来像'David'或名字听起来像'David')。如果它只是约翰,它只会在 AND 之前执行第一部分 - 所以它确实匹配。但可能不是最有效的方法,对吧? 是的,可能。然后我的解决方案就变成了一个真正不存在的问题的解决方法...... :)以上是关于将多条查询结果作为like查询条件的主要内容,如果未能解决你的问题,请参考以下文章
ORACLE模糊查询语句 当条件为 like %(% 或者like %)%时 结果为全查吗
PHP/MySQL:突出显示“SOUNDS LIKE”查询结果