MYSQL: Can you pull results that match like 3 out of 4 expressions?

前端 未结 5 1180
眼角桃花
眼角桃花 2021-02-08 11:50

Say I have a query like this:

SELECT * FROM my_table WHERE name = \"john doe\" AND phone = \"8183321234\" AND email = \"johndoe@yahoo.com\" AND address = \"330 s         


        
相关标签:
5条回答
  • 2021-02-08 12:24

    Holy overcomplexity, Batman.

    SELECT * 
    FROM my_table 
    WHERE (
        (name = "john doe") +
        (phone = "8183321234") +
        (email = "johndoe@yahoo.com") +
        (address = "330 some lane")
    ) >= 3;
    
    0 讨论(0)
  • 2021-02-08 12:24

    I like the IF construct:

    SELECT * FROM my_table
    WHERE
    (    IF(name    = 'john doe', 1, 0) +
         IF(phone   = '8183311234', 1, 0) +
         IF(email   = 'johndoe@yahoo.com', 1, 0) +
         IF(address = '330 some lane', 1, 0)
    ) >= 3
    
    0 讨论(0)
  • 2021-02-08 12:31

    Same thing using indexes:

    SELECT  *
    FROM    (
            SELECT  id
            FROM    (
                    SELECT  id
                    FROM    mytable _name
                    WHERE   name = 'john doe'
                    UNION ALL
                    SELECT  id
                    FROM    mytable _name
                    WHERE   phone = '8183321234'
                    UNION ALL
                    SELECT  id
                    FROM    mytable _name
                    WHERE   email = "johndoe@yahoo.com"
                    UNION ALL
                    SELECT  id
                    FROM    mytable _name
                    WHERE   address = '330 some lane'
                    ) q
            GROUP BY 
                    id
            HAVING
                    COUNT(*) >= 3
            ) di, mytable t
    WHERE   t.id = di.id
    

    See the entry in my blog for performance details.

    0 讨论(0)
  • 2021-02-08 12:32

    Modifying Tomalak's query slightly so that it will use indexes if they are present. Although unless there is an index on each field, a full table scan will happen anyway.

    SELECT
    *, 
    (
        IF(name="john doe", 1, 0) +
        IF(phone = "8183321234", 1, 0) +
        IF(email = "johndoe@yahoo.com", 1, 0) +
        IF(address = "330 some lane", 1, 0) 
    ) as matchCount
    FROM my_table 
    WHERE 
        name = "john doe" OR 
        phone = "8183321234" OR 
        email = "johndoe@yahoo.com" OR 
        address = "330 some lane"
    HAVING matchCount >= 3
    
    0 讨论(0)
  • 2021-02-08 12:40
    SELECT
      * 
    FROM 
      my_table 
    WHERE 
      CASE WHEN name = "john doe"           THEN 1 ELSE 0 END +
      CASE WHEN phone = "8183321234"        THEN 1 ELSE 0 END +
      CASE WHEN email = "johndoe@yahoo.com" THEN 1 ELSE 0 END +
      CASE WHEN address = "330 some lane"   THEN 1 ELSE 0 END
      >= 3;
    

    Side note: this will very likely not be using indexes efficiently. On the other hand, there will very likely be no indexes on these kinds of columns anyway.

    0 讨论(0)
提交回复
热议问题