2

我正在编写一个查询来使用全文搜索来搜索 mysql 表:

select title, 
  MATCH(title,sidebarTxt,introTxt,fullTxt) AGAINST ('MY KEYWORDS' IN NATURAL LANGUAGE MODE) AS score 
from tbl_news
where (status='published') 
order by score DESC

上面的查询运行良好。但是,如果我尝试在 where 子句中使用 'score',MySql 会抛出错误“#1054 - 'where 子句'中的未知列'score'。这是不工作的代码:

select title, 
  MATCH(title,sidebarTxt,introTxt,fullTxt) AGAINST ('MY KEYWORDS' IN NATURAL LANGUAGE MODE) AS score 
from tbl_news
where status='published' and score > 0 
order by score DESC

如果您能帮助我理解它,我将不胜感激。

4

4 回答 4

3

如果是计算列,则不能scoreWHERE子句中使用。score您必须在附加HAVING子句中设置它以在计算应用条件:

SELECT title, 
  MATCH(title,sidebarTxt,introTxt,fullTxt)
      AGAINST ('MY KEYWORDS' IN NATURAL LANGUAGE MODE) AS score 
FROM tbl_news
WHERE status='published'
HAVING score > 0
ORDER BY score DESC;

一个测试用例(使用不同的表)。这里host是一个列,host2是一个派生列。当然,列推导和选择是虚假的,没有什么意义:

mysql> use mysql;
Database changed
mysql> select host, UPPER(host) as host2 FROM user WHERE host = 'nottingham';
+------------+------------+
| host       | host2      |
+------------+------------+
| nottingham | NOTTINGHAM |
+------------+------------+
1 row in set (0.00 sec)

mysql> select host, UPPER(host) as host2 FROM user WHERE host = 'nottingham' AND host2 = 'NOTTINGHAM';
ERROR 1054 (42S22): Unknown column 'host2' in 'where clause'
mysql> select host, UPPER(host) as 'host2' FROM user WHERE host = 'nottingham' AND host2 = 'NOTTINGHAM';
ERROR 1054 (42S22): Unknown column 'host2' in 'where clause'
mysql> select host, UPPER(host) as `host2` FROM user WHERE host = 'nottingham' AND host2 = 'NOTTINGHAM';
ERROR 1054 (42S22): Unknown column 'host2' in 'where clause'

mysql> select host, UPPER(host) as host2 FROM user WHERE host = 'nottingham' HAVING host2 = 'NOTTINGHAM';
+------------+------------+
| host       | host2      |
+------------+------------+
| nottingham | NOTTINGHAM |
+------------+------------+
1 row in set (0.00 sec)
于 2012-09-13T15:09:44.403 回答
2

问题是score在查询完成运行之前,所有行的值都不知道。因此,这不可能在score使用该WHERE子句时应用条件。在ORDER BY计算完所有结果行之后执行,因此使用它没有问题。

尝试使用HAVING

SELECT title, MATCH(title,sidebarTxt,introTxt,fullTxt) AGAINST ('MY KEYWORDS' IN NATURAL LANGUAGE MODE) AS score
FROM tbl_news
WHERE status='published'
HAVING score > 0
ORDER BY score DESC

HAVING子句的行为几乎类似于WHERE,不同之处是在计算结果行之后执行。此时,score每个结果行的值都是已知的,可以应用条件。

文档:
全文搜索:查看示例,它们使用HAVING
SELECT 语法:查看有关HAVING用法的部分

于 2012-09-13T15:24:06.067 回答
0

编辑:错误

尝试将单引号添加到:as 'score'...它似乎无法识别您指定该列的名称。

于 2012-09-13T15:07:05.047 回答
0

这很可能是 50% 噪声的情况。当你有一个单词在 50% 或更多的行中时,mysql 认为它是一个干扰词,并且在评分时会忽略它(因此排名)。这仅适用于该NATURAL LANGUAGE MODE选项。

不要吹毛求疵,但它应该工作得很好,没有任何引号:

mysql> select * from table1;
+---------+------+------+-------------+
| autonum | ID   | name | metavalue   |
+---------+------+------+-------------+
|       1 |    1 | Rose | Drinker     |
|       2 |    1 | Rose | Nice Person |
|       3 |    1 | Rose | Runner      |
|       4 |    2 | Gary | Player      |
|       5 |    2 | Gary | Funny       |
|       6 |    2 | Gary | NULL        |
|       7 |    2 | Gary | Smelly      |
+---------+------+------+-------------+
7 rows in set (0.00 sec)

mysql> select ID, group_concat(coalesce(metavalue,'Empty')) as Test from table1 group by ID order by Test;
+------+----------------------------+
| ID   | Test                       |
+------+----------------------------+
|    1 | Drinker,Nice Person,Runner |
|    2 | Player,Funny,Empty,Smelly  |
+------+----------------------------+
2 rows in set (0.01 sec)

mysql> select ID, group_concat(coalesce(metavalue,'Empty')) as Test from table1 group by ID order by Test desc;
+------+----------------------------+
| ID   | Test                       |
+------+----------------------------+
|    2 | Player,Funny,Empty,Smelly  |
|    1 | Drinker,Nice Person,Runner |
+------+----------------------------+
2 rows in set (0.00 sec)

Server version: 5.5.24-0ubuntu0.12.04.1 (Ubuntu)

(并且这种查询在我的 Windows 5.1.x 安装中也可以正常工作)

于 2012-09-13T15:07:40.367 回答