现有如下表,字段类型全是int,表中已有数据:
id      x1    x2    x3    x4
1       1     1     1     1
2       1     1     1     2
3       1     1     3     3用户输入检索条件:
x1    x2    x3    x4
1     1     1     1
能检索出第1,2条数据,第3条不满足,即:x1,x2,x3,x4中,有三个或以上相同的,就符合条件。
最简单的就是:
(x1=1 AND x2=1 AND x3=1) OR
(x1=1 AND x2=1 AND x4=1) OR
(x1=1 AND x3=1 AND x4=1) OR
(x2=1 AND x3=1 AND x4=1)问题是如何写sql语句效率才能最好(每个字段都有索引),有没有比上面效率更好的sql?
谢谢!

解决方案 »

  1.   

      SELECT * FROM table WHERE concat(case when x1 =1 then '1' else '0' end,case when x2 =1 then '1' else '0' end,case when x3 =1 then '1' else '0' end,case when x4 =1 then '1' else '0' end) like '%1%1%1%'
    但不知道效率是否提高了,仅供参考
      

  2.   

    楼主的数据是举了简单例子,还是泛指,如果就是泛指,可以用数字方法处理:
    (x1 + x2 + x3 + x4)<= 5 
      

  3.   

    你这个是实际应用还是考试题?你的索引是不是4个,每个独自建索引?有没有主键?语句写法最简单的:
    SELECT *
      FROM x
     WHERE (x1 = 1) + (x2 = 1) + (x3 = 1) + (x4 = 1) >= 3想了半天,没有能够利用索引的。
      

  4.   


    x1,x2,x3,x4要是5,6,7,8呢?
    而且没用到索引
      

  5.   

    select * from table1
    where (x1=1) + (x2=1) + (x3=1) + (x4=1) >2;这种方法看上去简单。但无法利用索引!
      

  6.   

    想了一晚上,似乎必须得换表结构才能够用到索引
    比如加主键id,索引变成(x1,x2,x3) (x1,x2,x4) (x1,x3,x4) (x2,x3,x4)SELECT * FROM x USE INDEX(index_123)
    WHERE
    (x1=1 AND x2=1 AND x3=1)
    UNION
    SELECT * FROM x USE INDEX(index_124)
    WHERE
    (x1=1 AND x2=1 AND x4=1)
    UNION
    SELECT * FROM x USE INDEX(index_134)
    WHERE
    (x1=1 AND x3=1 AND x4=1)
    UNION
    SELECT * FROM x USE INDEX(index_234)
    WHERE
    (x2=1 AND x3=1 AND x4=1)
      

  7.   

    对,虽然SQL语句长了点,但能用索引
      

  8.   

    而且后面的use index推荐必须手工添加,否则很可能出现
    (x1=1 AND x2=1 AND x4=1) 使用index_123 + where的情况
      

  9.   

    应该不需要,MYSQL会根据条件进行索引的 merge 运算。
    当然前提是你符合条件的结果不会太多。则MYSQL会根据每个 OR 部分分别使用相对应的索引。然后对索引的结果进行 merge 运算。
      

  10.   


    这个建索引的想法不错,效率肯定有提升。
    然后我觉得上面ACMAIN_CHM说得也对,mysql会自己决定如何使用索引的,因此我觉得只要索引建成(x1,x2,x3) (x1,x2,x4) (x1,x3,x4) (x2,x3,x4),sql写成
    (x1=1 AND x2=1 AND x3=1) OR 
    (x1=1 AND x2=1 AND x4=1) OR 
    (x1=1 AND x3=1 AND x4=1) OR 
    (x2=1 AND x3=1 AND x4=1) 
    mysql就可以自己对每一个分别用相应的索引了,不用union。这应该就是最好的方法了,多谢各位!
      

  11.   

    你后面说的哪种不会必然导致index,你可以多造点数据,explain一下