powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Переписать запрос
18 сообщений из 18, страница 1 из 1
Переписать запрос
    #39439058
SqlDreamer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Довольно распространенная задача, фильтры по входным параметрам (параметры могут быть, а могут и не быть).
Т.е. упрощенно, в наличии две таблицы,
надо вывести все записи из первой таблицы, в привязке ко второй (параметры),
но если во второй записей нет (параметры не заданы), то из первой вывести все записи. Без дин.скл.
Обычно что-то типа такого:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
create table table1
as
select level lvl
  from dual connect by level<1000000;
  
create table table2
as
select cast(null as number) lvl from dual where 1=2;

-- вариант 1
with t2 as (select count(*) cnt from table2)
select t1.*
  from table1 t1, t2
 where t2.cnt = 0
    or (t2.cnt > 0 and t1.lvl in (select lvl from table2 t3));
    
-- вариант 2    
with t2 as (select null lvl 
             from dual
            where 0 = (select count(*) cnt from table2)
            union all
            select lvl from table2)
select t1.*
  from table1 t1, t2
 where t1.lvl = nvl(t2.lvl, t1.lvl);


По сути не сильно отличаются по-моему и вроде работает,
но что-то не нравится (в первом случае каждый раз проверка t2.cnt, во втором NVL)
и ощущение, что можно переписать как-то более изящно что ли.
...
Рейтинг: 0 / 0
Переписать запрос
    #39439065
Фотография Elic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SqlDreamerДовольно распространенная задача, фильтры по входным параметрам (параметры могут быть, а могут и не быть).
Т.е. упрощенно, в наличии две таблицы,
надо вывести все записи из первой таблицы, в привязке ко второй (параметры),
но если во второй записей нет (параметры не заданы), то из первой вывести все записи.Каждый кулик своёболото считает образцом для подражания.
SqlDreamerОбычно что-то типа такого:Обычно используют bind-ы. А если приложение недо-, то обычно с этого и начинают.
...
Рейтинг: 0 / 0
Переписать запрос
    #39439119
SqlDreamer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
ElicОбычно используют bind-ы. А если приложение недо-, то обычно с этого и начинают.
Чота вы сегодня не с той ноги, сразу болтом обзываетесь ) между тем действительно встречал немало болот, где используют подобный подход. Бинды конечно есть, по ним и достаются данные в table2, здесь упростил, чтобы отразить суть вопроса.
То есть данные из table2 достаются по биндам, а далее они являются фильтром для table1, но если в table2 ничего не попало, то из table1 надо достать все.
...
Рейтинг: 0 / 0
Переписать запрос
    #39439185
ora601
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SqlDreamerТ.е. упрощенно, в наличии две таблицы,
надо вывести все записи из первой таблицы, в привязке ко второй (параметры),
но если во второй записей нет (параметры не заданы), то из первой вывести все записи. Без дин.скл.


LEFT JOIN ?? :)
...
Рейтинг: 0 / 0
Переписать запрос
    #39439262
SqlDreamer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
ora601LEFT JOIN ?? :)
Типа такого?
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
with t2 as (select lvl 
              from table1
             where 0 = (select count(*) cnt from table2)
             union all
            select lvl from table2)
select t1.*
  from t2, table1 t1
 where t2.lvl = t1.lvl(+);


Но тогда если в table2 нет записей, то джоин как бы вообще не нужен. Выходит, только дин.скл.
...
Рейтинг: 0 / 0
Переписать запрос
    #39442468
Фотография JaRo
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: plsql
1.
2.
3.
4.
5.
select lvl from (
select table1.*, table2.lvl t2_lvl, count(table2.lvl) over () cou
from table1, table2
where table1.lvl = table2.lvl(+)
) where cou = 0 or t2_lvl is not null

PS: lvl во второй таблице ведь не может быть null? ну или если может, то это не считается "в привязке ко второй" или как?
...
Рейтинг: 0 / 0
Переписать запрос
    #39442481
ora601
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SqlDreamer,

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
with t2_cnt AS 

(SELECT COUNT(*) cnt FROM t2)

SELECT t1.* 
FROM t1 LEFT JOIN t2 ON t1.id=t2.id

WHERE t2.id IS NOT NULL OR (SELECT cnt FROM t2_cnt) = 0 
 
...
Рейтинг: 0 / 0
Переписать запрос
    #39443295
MaximaXXL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SqlDreamer,

ну извратиться конечно можно =)

Код: plsql
1.
2.
3.
select t1.*
from t1, (select nvl(t2.lvl,null) lvl from dual left join t2 on (t2.f= :param/*условие на t2*/)) t3
where t1.lvl = nvl(t3.lvl, t1.lvl)
...
Рейтинг: 0 / 0
Переписать запрос
    #39443298
MaximaXXL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MaximaXXL,

даже так, точнее:
Код: plsql
1.
2.
3.
select t1.*
from t1, (select t2.lvl from dual left join t2 on (t2.f= :param/*условие на t2*/)) t3
where t1.lvl = nvl(t3.lvl, t1.lvl)



ну в общем мысль понятна ...
...
Рейтинг: 0 / 0
Переписать запрос
    #39443328
Фотография dbms_photoshop
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MaximaXXLну в общем мысль понятна ...Непонятно только почему ты приплел :param.

Если цель решить задачу ТС с одним проходом каждой из таблиц и без всяких аналитических сортировок,
то это можно (но не нужно) сделать примерно так
Код: plsql
1.
select * from t1 join dual left join t2 on 0 = 0 on t1.id = nvl(t2.id, t1.id)


В 12с вместо нелепого left join можно было бы использовать lateral/outer apply.
...
Рейтинг: 0 / 0
Переписать запрос
    #39443452
MaximaXXL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dbms_photoshopНепонятно только почему ты приплел :param.
......
В 12с вместо нелепого left join можно было бы использовать lateral/outer apply.

ну это я в шар хрустальный глянул и понял что SqlDreamer будет передавать условия во внутреннюю таблицу и если записей нет то выдать все (так и писал)

по 12с - мы еще на 11 посему outer join пока
...
Рейтинг: 0 / 0
Переписать запрос
    #39443463
Фотография dbms_photoshop
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MaximaXXL,

Вроде ТС довольно четко объяснил, что если t2 пустая, то выдаются все записи t1, иначе фильтруются по t2.
...
Рейтинг: 0 / 0
Переписать запрос
    #39443479
SqlDreamer,

Код: plsql
1.
select * from t1, t2 where t1.lvl = nvl(t2.lvl,t1.lvl)
...
Рейтинг: 0 / 0
Переписать запрос
    #39443480
Пардоньте
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Неужели всё так просто?,

Код: plsql
1.
select t1.* from table1 t1, table2 t2 where t1.lvl = nvl(t2.lvl,t1.lvl)
...
Рейтинг: 0 / 0
Переписать запрос
    #39443488
Фотография dbms_photoshop
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ПардоньтеНеужели всё так просто?,

Код: plsql
1.
select t1.* from table1 t1, table2 t2 where t1.lvl = nvl(t2.lvl,t1.lvl)

Еще раз для танкистов: если t2 пустая - должны быть возвращены все строки из t1.

Неужели так сложно осилить формулировку из одной строки да еще и при наличии решений?
...
Рейтинг: 0 / 0
Переписать запрос
    #39443503
MaximaXXL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dbms_photoshop,

:param - это переменная для условия on (t2.f = значение)
Это ни в коем случае не часть аналитической функции

т.е. я выделил место где задавать условие, отлаживался я так =)
...
Рейтинг: 0 / 0
Переписать запрос
    #39443518
MaximaXXL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dbms_photoshopMaximaXXL,

Вроде ТС довольно четко объяснил, что если t2 пустая, то выдаются все записи t1, иначе фильтруются по t2.

так и было написано, основной момент был указан что делать dual left Join table2 чтоб в случае пустой table2 после наложения условий была хотя-бы одна строка на выходе, значением которой можно управлять посредством nvl(t2.lvl,значение_для_пустой_таблицы). Но посмотрев в условие и увидев что SqlDreamer подходит null я просто заменил nvl(t2.lvl,значение_для_пустой_таблицы) на t2.lvl.

Ваш вариант более предпочтителен в конкретно поставленной задаче, я не спорю
...
Рейтинг: 0 / 0
Переписать запрос
    #39443526
Фотография dbms_photoshop
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MaximaXXL,

Более предпочтительна здесь скорее всего динамика, с генерацией in (list) вместо t2 по мере необходимости.
Но, я думаю, мы друг друга поняли.
...
Рейтинг: 0 / 0
18 сообщений из 18, страница 1 из 1
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Переписать запрос
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]