我已经创建了一个表来满足一些客户的需求,并且必须对要存储在表中的数据进行查询。我无法找出编写查询的最佳方式。
我的表结构如下:
c1 c2_lower_limit c2_upper_limit c3_lower_limit c3_upper_limit rate operator
1 0 10000 0 20000 10 AND
1 10000 50000 20000 30000 20 OR
1 50000 NULL 30000 NULL 30 OR
2 0 10000 0 20000 10 AND
2 10000 50000 20000 30000 20 OR
2 50000 NULL 30000 NULL 30 OR
用户指定C1
的值,然后指定C2
和C3
的值(c2只有一个值,c3有一个值)。假设我必须将rate列作为输出返回。表结构中的最后一列是OPERATOR
,它告诉我C2
和C3
值应该是AND
还是OR
。
我在确定要使用的运算符时遇到问题。用户可以根据自己的判断选择任何值以获得下限和上限。我尝试仅将操作员选择基于一个组 - 让我们说C2
,但那时这是不对的,因为我需要评估用户输入的所有变量,以获得正确的运算符。
假设用户为c2输入0
的值,并为25000
的c3输入值c1 = 1
。由于c3的值对应于opeartor值为OR
的条目,因此我应该OR
c2和c3限制值。简而言之,如果找到OR
运算符的记录,我必须OR
c2和c3组。
您可以检查SQLFiddle表格结构http://www.sqlfiddle.com/#!4/f9bf6/11
答案 0 :(得分:1)
快速而肮脏的解决方案可能是在operator
字段上添加条件。
使用:
表示法表示传递的参数:
SELECT *
FROM my_table
WHERE c1 = :c1
AND ((operator = 'AND'
AND
(:c2 BETWEEN c2_lower_limit AND c2_upper_limit OR
(:c2 >= c2_lower_limit AND c2_upper_limit IS NULL) OR
(c2_lower_limit IS NULL AND :c2 < c2_upper_limit)
AND
(:c3 BETWEEN c3_lower_limit AND c3_upper_limit OR
(:c3 >= c3_lower_limit AND c3_upper_limit IS NULL) OR
(c3_lower_limit IS NULL AND :c3 < c3_upper_limit)
)
OR
(operator = 'OR'
AND
(:c2 BETWEEN c2_lower_limit AND c2_upper_limit OR
(:c2 >= c2_lower_limit AND c2_upper_limit IS NULL) OR
(c2_lower_limit IS NULL AND :c2 < c2_upper_limit)
OR
(:c3 BETWEEN c3_lower_limit AND c3_upper_limit OR
(:c3 >= c3_lower_limit AND c3_upper_limit IS NULL) OR
(c3_lower_limit IS NULL AND :c3 < c3_upper_limit)
)
)
修改强>
请注意,有很多代码重复性处理带有null
操作的between
。如果你可以改变数据库,我会添加一个辅助函数来执行此操作:
CREATE OR REPLACE FUNCTION null_safe_between
(eval NUMBER, lower NUMBER, upper NUMBER)
RETURN BOOLEAN
DETERMINISTIC
BEGIN
RETURN eval BETWEEN lower_limit AND upper_limit OR
(eval >= lower_limit AND upper_limit IS NULL) OR
(lower_limit IS NULL AND eval < upper_limit);
END;