我在选择查询时需要帮助,但在提出问题之前,我将简要介绍一下我的系统是如何工作的:
我的数据库有多对多的关系:
table product:
prd_cod(pk) //stores the product code ex: 0,1,2
cat_cod(fk)
prd_name //stores the product name, ex: tv, gps, notebook
table description_characteristc:
prd_cod(fk)
id_characteristic(fk)
description //stores the description of the characteristic, ex: sony, 1kg, hj10
table characteristic:
id_characteristic (pk)
name_characteristic //store the name of characteristic, ex: brand, weight, model
我已经建议jQuery(在index.php中),我输入的每个单词都调用suggest.php,它会生成一个select并将结果返回到索引中的建议框中:
<?php
header('Content-type: text/html; charset=UTF-8');
$hostname = 'localhost';
$username = 'root';
$password = '';
$dbname = 'cpd';
mysql_connect($hostname, $username, $password)or die('Erro ao tentar conecta o banco
de dados.');
mysql_select_db( $dbname );
if( isset( $_REQUEST['query'] ) && $_REQUEST['query'] != "" )
{
$q = mysql_real_escape_string( $_REQUEST['query'] );
if( isset( $_REQUEST['identifier'] ) && $_REQUEST['identifier'] == "sugestao")
{
$sql = "SELECT p.prd_name, d.description
FROM product p
INNER JOIN description_characteristc d using (prd_cod)
WHERE '".$q."' like concat(p.prd_name, '%') AND
concat(p.prd_name, ' ', d.description) like concat('".$q."', '%')LIMIT 10";
$r = mysql_query( $sql );
if ( $r )
{
echo '<ul>'."\n";
$cont = 0;
while( $l = mysql_fetch_array( $r ) ){
$p = $l['nome'];
$p = preg_replace('/(' . $q . ')/i', '<span style="font-
weight:bold;">$1</span>',
$l['prd_nome'].' '.$l['descricao'].' '.$l['descricao']);
echo "\t".'<li id="autocomplete_'.$cont.'"
rel="'.$l['prd_nome'].'.'.$l['descricao'].'">'. utf8_encode( $p ) .'</li>'."\n";
$cont++;
}
echo '</ul>';
}
}
}
?>
以下是我的问题:
目前,当用户输入“t”时,只有当用户输入“tv”才会显示结果时,选择才会带来任何结果:
tv led
tv plasm
tv samsumg
我希望当用户输入't'时,选择为我带来'电视'。
当你输入'tv plasm'时,它会带来两次相同的name_character:
ex: tv plasm plasm
目前我的select选择了prd_name和表description_characteristc的描述:
tv led
我希望我的选择也可以进行反向选择,例如:led tv
。
我希望在显示选择结果时,可能会有一个缓存功能,显示最少寻求的顺序;记住prd_name只存储'tv'。
我正在寻找的帮助可以采用select的形式,如过程的形式。另外,我可以编辑php文件。
答案 0 :(得分:1)
您严重使用LIKE
条款,而您似乎并不知道“AND”的含义。将“和”用于编程时使用的“和”中的“和”是很重要的。在编程中意味着“两者都必须是正确的”。 “和”在随意的演讲中可能意味着“其中一个条件,你知道我的意思吗?”
另外,你不应该像这样构建SQL,这是一个等待发生的事故。你真的应该找到一种方法将变量绑定到SQL语句中。我不懂PHP,所以我无法帮助。
首先,您应该在WHERE子句p.prd_name LIKE '$q%'
中使用它。在PHP之外 - 在Web之外 - 尝试这个,就像一个简单的SQL查询:SELECT * FROM PRODUCT P WHERE P.PRD_NAME LIKE 'T%'
。
其次,你应该将“AND”修改为“OR”,因为你想要一个条件或其他条件为真。如果你想要两个条件都是真的,几乎没有任何东西可以匹配。
答案 1 :(得分:1)
您应该在PHP
方面拆分并加入您的搜索查询,如下所示:
<?php
$words = preg_split("/[^\\w]+/", $q);
$first = $words[0] + "%";
$all = implode(" ", $words) + "%";
?>
然后在此查询中使用变量$first
和$all
:
SELECT p.prd_name, d.description
FROM product p
JOIN description d
ON d.prd_cod = p.prd_cod
WHERE p.prd_name LIKE '$first'
AND CONCAT(p.prd_name, ' ', d.description) LIKE '$all'
在product (prd_name)
上创建一个索引,以便快速工作。
如果您希望以任何顺序匹配单词,则必须在表格上创建FULLTEXT
索引(这仅适用于MyISAM
):
CREATE FULLTEXT INDEX fx_product_name ON product (prd_name)
CREATE FULLTEXT INDEX fx_description_name ON description (description)
并编写如下查询:
SELECT p.prd_name, d.description
FROM (
SELECT prd_cod
FROM product pi
WHERE MATCH(prd_name) AGAINST ('lcd tv' IN BOOLEAN MODE)
UNION
SELECT prd_cod
FROM description di
WHERE MATCH(description) AGAINST ('lcd tv' IN BOOLEAN MODE)
) q
JOIN product p
ON p.prd_cod = q.prd_cod
JOIN description d
ON d.prd_cod= p.prd_cod
WHERE MATCH(p.prd_name, d.description) AGAINST ('+lcd +tv' IN BOOLEAN MODE)
请注意搜索字词语法更改:内部查询中的'lcd tv'
和外部查询中的'+lcd +tv'
。
您可能还希望将@@ft_min_word_len
设置为1
,以便匹配tv
或gps
等较短的字词。
由于MySQL
无法一次从两个或多个表构建全文索引,因此如果对表进行非规范化并将prd_name
放入description
表,则会更简单。这样,你可以摆脱连接,然后写:
SELECT prd_name, description
FROM description d
WHERE MATCH(prd_name, description) AGAINST ('+lcd +tv' IN BOOLEAN MODE)