Case в Where

 
0
 
Oracle
ava
m9yt | 09.08.2016, 15:59
Привет всем.
Пытаюсь написать запрос, который бы в зависимости от параметра производил фильтрацию строк по определенному условию.
Т.е. хотел бы получить что-то типа такого:
[code=sql]
SELECT *
  FROM m_user m
WHERE m.KEY IN CASE
                   WHEN :usr = -1
                   THEN
                      m.KEY                      -- вернуть всех пользователей
                   WHEN :usr = 0
                   THEN
                      (SELECT m2.KEY
                         FROM m_user m2
                        WHERE m2.sex = 1) -- отфильтровать людей по полу. Но вот тут как раз возвращается несколько строк, что выдает ошибку
                   ELSE
                      :usr                 -- вернуть конкретного пользователя
                END
[/code
Как можно иначе написать запрос, чтобы была поддержка фильтрации в зависимости от параметра?
Comments (7)
ava
Akina | 09.08.2016, 16:14 #

SELECT *
FROM m_user m
WHERE m.KEY IN (
                 SELECT CASE :usr
                        WHEN -1 THEN m.KEY
                        WHEN  0 THEN m2.KEY
                                ELSE :usr
                        END
                 FROM m_user m2
                 WHERE m2.sex = 1
                )

?
ava
Akina | 09.08.2016, 16:22 #
UPD. Написал ответ, но был невнимателен. Удалил, переписываю.

Суть:

SELECT *
FROM m_user m
WHERE m.KEY IN
(
SELECT
-- Вот тут все твои условия и раскручивай
CASE :usr
WHEN -1 THEN m.KEY
WHEN 0 THEN CASE t.sex WHEN 1 THEN t.KEY ELSE 0 END
ELSE :usr
END
FROM my_table t
)

Но это только суть, на самом деле надо всё то же, но без WHERE IN, а на основе m LEFT JOIN t.

Рекомендация: три отдельных запроса, а хоть бы и в рамках одной ХП.
ava
LSD | 09.08.2016, 19:21 #

select * from table where :usr = -1 and ...
union
select * from table where :usr = 0 and ...
union
select * from table where :usr not in (-1, 0) and ...
ava
Zloxa | 11.08.2016, 20:50 #
Цитата (LSD @  9.8.2016,  20:21 findReferencedText)
:usr not in (-1, 0)

это не альтернатива кляузы else. Надо еще допустить null
Цитата (LSD @  9.8.2016,  20:21 findReferencedText)
union

union all
ava
LSD | 15.08.2016, 14:24 #
Цитата (Zloxa @  11.8.2016,  21:50 findReferencedText)
union all

А зачем? Там же взаимоисключающие условия?
ava
Akina | 15.08.2016, 14:25 #
Цитата (LSD @  15.8.2016,  15:24 findReferencedText)
А зачем? Там же взаимоисключающие условия? 

А чтобы исключить операцию сортировки в тщетной попытке найти и отсеять дубликаты.
ava
Zloxa | 15.08.2016, 20:53 #
Цитата (LSD @  15.8.2016,  15:24 findReferencedText)
А зачем?

union и union all суть разные операции. Нелепо явно указывать одну операцию, полагая, что неявно вместо нее всегда будет выполняться другая. :unknw

Цитата (LSD @  15.8.2016,  15:24 findReferencedText)
Там же взаимоисключающие условия? 

Даже если отработает лишь один запрос из объединяемых, к нему все равно будет применен distinct

Цитата (Akina @  15.8.2016,  15:25 findReferencedText)
А чтобы исключить операцию сортировки в тщетной попытке найти и отсеять дубликаты. 

С огромной долей вероятности, ненужной сотртировки тут не будет. Выбирается по звездочке, в таблице наверняка есть PK. Конечно, для пущей надёги, можно бы еще и rowid в select list вписать, чтоб вместо указанного union железобетонно выполнялся union all  :girl_crazy 
Please register or login to write.
Firm of day
Вы также можете добавить свою фирму в каталог IT-фирм, и публиковать статьи, новости, вакансии и другую информацию от имени фирмы.
Подробнее
Contributors
ava  LSD   Akina ava  Zloxa   m9yt
advanced
Submit