在两列表格中按术语搜索并按计数排名

时间:2012-10-31 21:08:17

标签: mysql search

我有一个表,InnoDB,列id(int),name(varchar)和info(text)。我需要使用给定的术语搜索表格的名称和信息列,并根据每个记录合并的两列中的“点击次数”将匹配记录从高到低排名。

我已经拖网了,但我以前从未做过类似这样的事情,发现它有点令人困惑......案例和比赛等等。

有人可以提供一些快速帮助吗?

据我所知:

SELECT count(*) as count
FROM artistmanager_artists WHERE
case when 'name' LIKE '%a%' then 1 else 0 end
+ case when 'info' LIKE '%a%' then 1 else 0 end
ORDER BY count ASC

('a'是搜索词)

返回一行一列'count',值为3 ......我猜是因为我在mo的表中有三条记录?

我也发现并尝试过这个:

SELECT *
FROM `artistmanager_artists`
WHERE `name` LIKE '%a%'
AND (
   `info` LIKE '%a%'
)
ORDER BY (
  (
      CASE WHEN `name` LIKE '%a%'
      THEN 1
      ELSE 0
      END
  ) + (
     CASE WHEN `info` LIKE '%a%'
     THEN 1
     ELSE 0
     END
  )
) DESC

当我知道它没有返回的记录包含很多'a'时,它返回了除一条记录之外的所有记录,没有明显的顺序!

2 个答案:

答案 0 :(得分:3)

以下内容将按与您的字词匹配的列数(0到2)对行进行排名:

SELECT (name LIKE '%a%') + (info LIKE '%a%') AS rnk
FROM artistmanager_artists
ORDER BY rnk DESC

这利用了一个事实,即布尔值,如LIKE的结果,由MySQL中的整数表示,0表示false,1表示true。所以你可以简单地添加它们,没有任何区别。

如果要查找多个计数,则可能必须编写一个循环遍历字符串的存储过程,因为没有基本字符串函数可以计算匹配项。除非数据量非常大,否则通过在应用程序中而不是在数据库服务器上计算这些计数可能会更好。

您的第一个代码段只返回任一列中包含a的行数。这是因为COUNT是一个聚合列,(在没有GROUP BY的情况下)会将所有行合并为一行。第二个代码段只会选择两个列中a的行,因此订购号始终为2,导致明显缺乏排序。

答案 1 :(得分:1)

我做到了!感谢@MvG的灵感。因为我的PHP比我的MySQL好得多,所以我通过以下方式解决了问题:(我正在使用Codeignite btw)

public function get_artists_search($search_term)
{
    $artists = array();
    $query = $this->db->query('SELECT id, name, info, (name LIKE "%' . $search_term . '%") + (info LIKE "%' . $search_term . '%") AS rnk FROM artistmanager_artists ORDER BY rnk DESC');
    foreach ($query->result() as $row)
    {
        // returned rows have at least one occurence in at least one of the two columns, so values are 1 or 2
        $artists[$row->id]['name'] = $row->name;
        $artists[$row->id]['info'] = $row->info;
        $artists[$row->id]['score'] = 0;
    }
    // now foreach returned row find occurence values.
    foreach($artists AS $key=>$artist)
    {
        $score_name = substr_count(strtoupper($artist['name']), strtoupper($search_term));
        $score_info = substr_count(strtoupper($artist['info']), strtoupper($search_term));
        $artists[$key]['score'] = $score_name+$score_info;
        unset($artists[$key]['name']);
        unset($artists[$key]['info']);
    }
    arsort($artists);
}

返回一个数组,其中记录的id为键和排名值,从高到低排序。我测试了它,它起作用,所以我很好。

感谢所有人提供横向思考的帮助!

相关问题