如何在SQL查询中正确添加多个AND和BETWEEN?

时间:2018-12-21 15:23:32

标签: mysql sql database phpmyadmin

我正在尝试构建具有多个依赖项的过滤器函数,但是当我在SQL查询中添加AND时,似乎未找到任何结果,但是如果我要在AND之前和之后使用查询进行搜索,则正确找到结果。

我尝试构建一个过滤器功能,使用户可以在范围之间进行过滤,例如:价格:100美元至200美元之间,方呎在30至80之间。

我的方法如下:

SELECT * FROM 'tableXY' WHERE value BETWEEN 100 AND 200 AND key ='price' 
AND value BETWEEN 2 AND 5 AND key = 'rooms'
AND value BETWEEN 40 AND 80 AND key = 'sqft'......and so on.

该表包含ID,foreign_id,键和值列。行中的键是价格,平方英尺,房间,地址等。 如果我为价格x和价格y之间的某个价格范围进行过滤,并且对n个房间和m个房间之间的房间进行过滤,则它仅应返回设置了适用的错误过滤器的结果。

我的方法没有找到结果,如果我使用OR而不是AND,它还会显示其他过滤器不正确执行的结果。

5 个答案:

答案 0 :(得分:2)

似乎您需要在orvalue的每对条件之间进行逻辑key运算:

SELECT *
FROM   tableXY
WHERE  (value BETWEEN 100 AND 200 AND key ='price' ) OR 
       (value BETWEEN   2 AND   5 AND key = 'rooms') OR
       (value BETWEEN  40 AND  80 AND key = 'sqft' ) -- etc...

注意:由于and的优先级比or高,因此并不一定要使用括号,但是括号确实使查询更易于阅读。

答案 1 :(得分:0)

我认为您想要汇总,因为这些值位于不同的行中:

SELECT something
FROM tableXY
GROUP BY something 
HAVING SUM( value BETWEEN 100 AND 200 AND key ='price' ) > 0 AND
       SUM( value BETWEEN 2 AND 5 AND key = 'rooms' ) > 0 AND
       SUM( value BETWEEN 40 AND 80 AND key = 'sqft' ) > 0 AND
       ......and so on.

答案 2 :(得分:0)

解决方案1 ​​:对于不同的键值,在条件之间使用or

SELECT * FROM 'tableXY' WHERE (value BETWEEN 100 AND 200 AND key ='price') 
OR (value BETWEEN 2 AND 5 AND key = 'rooms')
OR (value BETWEEN 40 AND 80 AND key = 'sqft')......and so on.

解决方案2 :您需要使用case when

SELECT * FROM 'tableXY' 
WHERE 1 = (
 case 
  when key ='price' and value BETWEEN 100 AND 200 
     then 1
  when key ='rooms' and value BETWEEN 2 AND 5
     then 1
.....
  else 0
 end
) 

这是为什么您的初始子句找不到记录的原因。您在条件集之间使用AND的初始方法基本上是选择 WHERE ... value BETWEEN 2 AND 5 AND... value BETWEEN 40 AND 80 显然没有结果

答案 3 :(得分:0)

如果您以与以下类似的方式使用并集:

QueryWithRoomCostFilter UNION  QueryWithRoomSizeFilter

然后发生的事情是,它获取与成本过滤器匹配的元组集100 $ -200 $,并将它们添加到结果集中,然后它将使用空间大小为40-80平方英尺的过滤器评估第二个查询,将这些元组添加到结果集中,有效地合并(合并)两个结果。在这种情况下,您可能会看到联合正在运行,就像您的条件之间存在OR一样。

我不经常在两者之间使用价值,但也许可以按照这些方法尝试一些事情,让我们知道它是否仍然无效。

SELECT * 
FROM table_name
WHERE (price BETWEEN 100 AND 200)
AND (rooms BETWEEN 2 AND 5)
AND (sqft BETWEEN 40 AND 80)

答案 4 :(得分:0)

如键值对表所示,您的数据为 long 格式,其中不同单位类型的数据值和指标位于两列中: key 。因此,每个AND条件都试图选择一个 key value 逻辑条件对,并且一次不能满足所有条件,除非像 price ,房间平方呎格式存储在其特定列中。

长期解决方案

在关系数据库中使用诸如SO post之类的实体属性值模型存在一个长期存在的争论。有效过滤相互包含条件的长期解决方案是将表重新设计为宽格式,其中值位于其自己的列中,并且使用AND条件进行查询要容易得多。

CREATE TABLE tableXY (
    `price` DOUBLE,
    `room` INT
    `sqlft` INT,
    ... OTHER indicators ...
);

SELECT * 
FROM tableXY 
WHERE `price` BETWEEN 100 AND 200
  AND `rooms` BETWEEN 2 AND 5
  AND `sqft` BETWEEN 40 AND 80

短期解决方案

但是现有长格式的短期解决方案是运行条件聚合以创建以下值的“伪列”: price rooms sqft < / em>。为任何静态属性(名称,位置,时间等)添加GROUP BY

CREATE TABLE tableXY (
    `key` VARCHAR(10),
    `value` INT
);

SELECT sub.* 
FROM 
   (SELECT CASE WHEN `key` = 'name' THEN `key` ELSE NULL END AS `name`,
           SUM(CASE 
                   WHEN `key` = 'price'
                   THEN `value`
                   ELSE NULL
               END) AS price,
           SUM(CASE 
                   WHEN `key` = 'rooms' 
                   THEN `value`
                   ELSE NULL
               END) AS rooms,
           SUM(CASE 
                   WHEN `key` = 'sqlft' 
                   THEN `value
                   ELSE NULL
               END) AS sqft,

           -- ...other values...

     FROM tableXY

     GROUP BY CASE WHEN `key` = 'name' THEN `key` ELSE NULL END
  ) AS sub

WHERE sub.price BETWEEN 100 AND 200
  AND sub.rooms BETWEEN 2 AND 5
  AND sub.sqft BETWEEN 40 AND 80