如何通过最佳匹配订购

时间:2016-07-10 13:34:18

标签: mysql sql operator-keyword sql-order-by

考虑这个OR查询:

SELECT * FROM course WHERE description LIKE '%university%' OR description LIKE '%history%'

显然,我希望首先看到两个条件都为真的记录,即包含'university''history'的记录,然后是仅包含其中一个的记录。

当我想将LIMIT放在那里时,这一点尤其重要。 知道如何在不循环所有结果的情况下做到这一点吗?

2 个答案:

答案 0 :(得分:0)

这很简单,您可以使用简单的顺序子句来实现所需的结果:

SELECT * FROM course
WHERE description LIKE '%university%' OR description LIKE '%history%'
ORDER BY IF(description LIKE '%university%' and description LIKE '%history%', 0, 1)
LIMIT 0, 20

即使您可以检索仅匹配universityhistory关键字的条目,也可以检索其他条目。

<强>更新

对于更复杂的搜索,最好实现MySQL的MATCH AGAINST功能,请参阅:否则LIKE子句不允许IN语句。您也可以使用这样的REGEXP:MySQL match() against() - order by relevance and column?

对于其他一些示例,您可以在WHERE子句中使用REGEXP,如下所示:

WHERE description REGEXP 'university|history|literature'

但是在这种情况下你仍然需要为ORDER子句构建相同的查询,就像我给出的第一个例子一样。

无论如何,如果你动态地构建这个字符串,那就不难了,但在这种情况下,ORDERing会很复杂。只有MATCH AGAINST才能解决您的问题。

答案 1 :(得分:0)

尝试类似的东西:

public extension DispatchQueue {

    private static var _onceTracker = [String]()

    /**
     Executes a block of code, associated with a unique token, only once.  The code is thread safe and will
     only execute the code once even in the presence of multithreaded calls.

     - parameter token: A unique reverse DNS style name such as com.vectorform.<name> or a GUID
     - parameter block: Block to execute once
     */
    public class func once(token: String, block:@noescape(Void)->Void) {
        objc_sync_enter(self); defer { objc_sync_exit(self) }

        if _onceTracker.contains(token) {
            return
        }

        _onceTracker.append(token)
        block()
    }
}

然后在查询结尾按排名排序。

只要您继续添加,就可以按两个以上的描述进行排名。