【问题标题】:MySQL matching 2 out of 5 fieldsMySQL 匹配 5 个字段中的 2 个
【发布时间】:2011-08-18 14:47:58
【问题描述】:

在 MySQL 中,我尝试选择与所提供数据的至少 2 个字段匹配的任何行

例如。我已获得名字、姓氏、出生日期、网站、电子邮件,我想要任何匹配名字和姓氏、名字和电子邮件、或网站和电子邮件等的行。

我知道我可以写一个长篇大论的声明 (this=this AND this=this) OR (this=this etc 但是这个查询可能会变得非常大,尤其是当我们决定要匹配超过 5 个字段时。

我们还需要对匹配的行进行排名,因此如果某些行匹配 3 而不仅仅是最少的 2 个字段,那么它们应该在返回的结果中显示得更高。

我可以在之后使用 PHP 处理这个,或者执行多个 SQL 查询,我只是想知道是否有人知道更简单/更干净的方法来匹配这些数据?

感谢您的帮助! 乔

【问题讨论】:

  • 我不认为 LONG SQL 会伤害任何东西

标签: mysql


【解决方案1】:

您可以计算匹配的表达式。 MySQL 返回 1 为真,0 为假。

WHERE (FirstName = ?) + (LastName = ?) + (... = ?) > 2

您也可以使用它来订购。您需要进行降序排序,以确保较高的匹配项首先出现。

ORDER BY ((FirstName = ?) + (LastName = ?) + (... = ?)) DESC

【讨论】:

    【解决方案2】:

    作为推荐的答案,您可以将值相加。如果你想用它来进行排名,你可能不会像他那样将它包含在 where 子句中。

    SELECT *, ((firstName = @inputFirst) + (lastName = @inputLast) + (dob = @inputDob) + (website = @inputWebsite) + (email = @inputEmail)) as Matches
    FROM mytable
    HAVING Matches > 1
    ORDER BY Matches DESC
    

    我目前无法访问 mysql 数据库来测试此语法,但我相信它应该可以正常工作。

    【讨论】:

    • 这就是我的想法,除了我认为你想要HAVING 而不是WHERE
    • @wiseguy 为什么有?这里没有分组,也不需要排序之后过滤
    • 因为Matches 不是表中的实际列。 WHERE 将条件放在表列上,而 HAVING 将条件放在结果集列上。
    • 不过,MySQL 并不关心。 AFAIK 可以在 WHERE 子句中使用别名。
    • "Standard SQL disallows references to column aliases in a WHERE clause. This restriction is imposed because when the WHERE clause is evaluated, the column value may not yet have been determined." dev.mysql.com/doc/refman/5.0/en/problems-with-alias.html
    【解决方案3】:
    SELECT
    (CASE WHEN Field1 = Value1 THEN 1 ELSE 0 END
    +CASE WHEN Field2 = Value2 THEN 1 ELSE 0 END
    ...
    +CASE WHEN FieldN = ValueN THEN 1 ELSE 0 END
    )
    AS Conditions
    From YourTable
    WHERE Conditions >= (Min_Number_Of_Fields)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-02-18
      • 1970-01-01
      • 1970-01-01
      • 2015-03-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多