2014-01-27 3 views
0

Я создал таблицу для удовлетворения некоторых требований клиентов и должен написать запрос на данные, которые будут храниться в таблице. Я не могу найти оптимальный способ написать мой запрос.Не удалось вычислить запрос

Моя таблица построена как:

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 и один для с3). Предположим, что мне нужно вернуть столбец скорости в качестве выходного. Последний столбец в структуре таблицы - OPERATOR, который говорит мне, должны ли значения C2 и C3 быть AND или OR ed.

Я столкнулся с проблемой при определении используемого опоры. Пользователь может выбрать любое значение по своему усмотрению для нижнего и верхнего пределов. Я попытался использовать мой оператор только в одной группе - допустим, C2, но тогда это неправильно, так как мне нужно оценить все переменные, вводимые пользователем для получения правильного оператора.

Предположим, что пользователь вводит значение 0 для c2 и вводит значение 25000 для c3 для c1 = 1. Так как значения c3 соответствуют записи с номером oterartor OR, я должен OR предельные значения c2 и c3. Короче говоря, если найдена запись с оператором OR, у меня есть OR группы c2 и c3.

Вы можете проверить SQLFiddle для таблицы структуры http://www.sqlfiddle.com/#!4/f9bf6/11

+1

И где ваш запрос в субоптимальной форме? – GolezTrol

+0

Привет @GolezTrol, я пропустил размещение моего запроса в окне SQLFiddle. Я опубликовал его сейчас. Я ошибался, утверждая, что это «не оптимально», на самом деле он даже не вернул правильные результаты. – Incognito

ответ

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) 
     ) 
     ) 

EDIT:
Обратите внимание, что есть много обработки 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; 
Смежные вопросы