我正在尝试构建具有多个依赖项的过滤器函数,但是当我在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,它还会显示其他过滤器不正确执行的结果。
答案 0 :(得分:2)
似乎您需要在or
和value
的每对条件之间进行逻辑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