powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Выбор промежуточных значений запросом
32 сообщений из 32, показаны все 2 страниц
Выбор промежуточных значений запросом
    #39368716
leprechaun
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Добрый день, подскажите пожалуйста

есть таблица например со значениями строк 1,2,3,4,5,6,7,8,9

и два параметра в запрос хочу передать, ограничивающие выборку сверху и снизу, к примеру 2 и 4
в этом случае нужно чтобы этот селект вывел значения 2,3,4
как это написать, сходу не сообразил.

Спасибо.
...
Рейтинг: 0 / 0
Выбор промежуточных значений запросом
    #39368717
londinium
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: sql
1.
...WHERE A.VALUE BETWEEN InMin AND InMax


?
...
Рейтинг: 0 / 0
Выбор промежуточных значений запросом
    #39368743
leprechaun
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Да, верно если это как в моем примере числа
А если есть таблица, на лету отсортированная ORDER BY 3, 2 колонкам

10, A, 1
13, B, 1
21, B, 1
14, C, 2
66, D, 2
55, D, 3
24, F, 3
11, E, 3

в параметры передается 2 значения первой колонки, к примеру 21 и 55
и в результате должен получить все значения этого диапазона

Как это красиво сделать? between не подходит вроде

Замудрил я, наверное всё просто)
...
Рейтинг: 0 / 0
Выбор промежуточных значений запросом
    #39368760
leprechaun
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
В общем из таблицы на лету отсортированной мне нужно выбрать все записи, начиная со стартовой (отсечь верхушку)

21, B, 1
14, C, 2
66, D, 2
55, D, 3
24, F, 3
11, E, 3

MINUS все значения после 55

24, F, 3
11, E, 3

и будет нужный массив.
...
Рейтинг: 0 / 0
Выбор промежуточных значений запросом
    #39368765
legg
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
leprechaunВ общем из таблицы на лету отсортированной мне нужно выбрать все записи, начиная со стартовой (отсечь верхушку)

21, B, 1
14, C, 2
66, D, 2
55, D, 3
24, F, 3
11, E, 3

MINUS все значения после 55

24, F, 3
11, E, 3

и будет нужный массив.
щитаю, что без критерия сортировки - никак. буду рад ошибиться.
...
Рейтинг: 0 / 0
Выбор промежуточных значений запросом
    #39368770
legg
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
leggleprechaun...
щитаю, что без критерия сортировки - никак. буду рад ошибиться.
а если как отсортирован массив понятно - то во вложенном запросе высчитать номер строки с значением 55 и в итоговом вывести строки с номерами строк меньше или равной высчитанной.
ну или можно с lead-lag поизвращаться.
м.б. что ловчее есть. в голову не приходит.
...
Рейтинг: 0 / 0
Выбор промежуточных значений запросом
    #39368778
leprechaun
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
хорошая мысль, только если я беру
select rownum from tab1
order by 1,5

то в номере строки каша, он вычисляется до сортировки
...
Рейтинг: 0 / 0
Выбор промежуточных значений запросом
    #39368790
legg
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
leggleggпропущено...

щитаю, что без критерия сортировки - никак. буду рад ошибиться.
а если как отсортирован массив понятно - то во вложенном запросе высчитать номер строки с значением 55 и в итоговом вывести строки с номерами строк меньше или равной высчитанной.
ну или можно с lead-lag поизвращаться.
м.б. что ловчее есть. в голову не приходит.
row_number () over (order by) надо пользовать. только у меня есть опасение что можно проще. как - не соображу чей-та
...
Рейтинг: 0 / 0
Выбор промежуточных значений запросом
    #39368791
Фотография SeaGate
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
leprechaun,

F после E.
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
with t(a,b,c) as (
select 10, 'A', 1 from dual union all
select 13, 'B', 1 from dual union all
select 21, 'B', 1 from dual union all
select 14, 'C', 2 from dual union all
select 66, 'D', 2 from dual union all
select 55, 'D', 3 from dual union all
select 24, 'F', 3 from dual union all
select 11, 'E', 3 from dual)
select a, b, c
  from t
 match_recognize
 (
   order by c,b
   all rows per match
   pattern (p21 smth* p55)
   define
     p21 as p21.a = 21,
     p55 as p55.a = 55,
     smth as 1=1
 )


Livesql
...
Рейтинг: 0 / 0
Выбор промежуточных значений запросом
    #39368793
legg
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SeaGate,
я даж слов таких не знаю %)
...
Рейтинг: 0 / 0
Выбор промежуточных значений запросом
    #39368806
stax..
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
leprechaunВ общем из таблицы на лету отсортированной мне нужно выбрать все записи, начиная со стартовой (отсечь верхушку)

21, B, 1
14, C, 2
66, D, 2
55, D, 3
24, F, 3
11, E, 3

MINUS все значения после 55

24, F, 3
11, E, 3

и будет нужный массив.
как то не могу одновременно понять начиная со стартовой и отсечь верхушку

отсечь верхунку
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
  1  with t (a,b,c) as (
  2  select 21, 'B', 1 from dual union all
  3  select 14, 'C', 2 from dual union all
  4  select 66, 'D', 2 from dual union all
  5  select 55, 'D', 3 from dual union all
  6  select 24, 'F', 3 from dual union all
  7  select 11, 'E', 3 from dual
  8  )
  9  , tt as (
 10  select t.*,sum(decode(a,55,1,0)) over (order by c desc,b desc) o from t)
 11* select a,b,c from tt where o=0 order by 3,2
 12  /

         A B          C
---------- - ----------
        11 E          3
        24 F          3




начиная с вехушки
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
  1  with t (a,b,c) as (
  2  select 21, 'B', 1 from dual union all
  3  select 14, 'C', 2 from dual union all
  4  select 66, 'D', 2 from dual union all
  5  select 55, 'D', 3 from dual union all
  6  select 24, 'F', 3 from dual union all
  7  select 11, 'E', 3 from dual
  8  )
  9  , tt as (
 10  select t.*,sum(decode(a,55,1,0)) over (order by c desc,b desc) o from t)
 11* select a,b,c from tt where o=1 order by 3,2
SQL> /

         A B          C
---------- - ----------
        21 B          1
        14 C          2
        66 D          2
        55 D          3



.....
stax
...
Рейтинг: 0 / 0
Выбор промежуточных значений запросом
    #39368813
arlx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
stax.., а так?

tt as
(select t.*, sum(decode(a, 55, 1, 0)) over(order by c desc, b desc) o1, sum(decode(a, 14, 1, 0)) over(order by c, b) o2
from t)
select a, b, c, o1, o2
from tt where o1=1 and o2 = 1
order by 3, 2
...
Рейтинг: 0 / 0
Выбор промежуточных значений запросом
    #39368818
stax..
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
arlxstax.., а так?

tt as
(select t.*, sum(decode(a, 55, 1, 0)) over(order by c desc, b desc) o1, sum(decode(a, 14, 1, 0)) over(order by c, b) o2
from t)
select a, b, c, o1, o2
from tt where o1=1 and o2 = 1
order by 3, 2

ето не ко мне, а к eprechaun

откуда 14? eprechaun надо данные с 14 по 55?

.....
stax
...
Рейтинг: 0 / 0
Выбор промежуточных значений запросом
    #39368823
arlx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
stax..,

для примера, развил идею
...
Рейтинг: 0 / 0
Выбор промежуточных значений запросом
    #39368829
Фотография SY
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
leprechaunи будет нужный массив.

У тебя "таблица, на лету отсортированная ORDER BY 3, 2 колонкам" а диапазон по колонке 1. Так-что верхняя грaница 55 может быть раньше нижней 21. Что тогда? И что если верхняя/нижняя грaница встречается несколько раз? И что если верхняя/нижняя грaница нe встречается? Сортировка по 3,2 неднозначна. У тебя две стоки с одинаковыми 3,2:

13, B, 1
21, B, 1

посeму неoпределено идeт ли 13 первым или 21. Судя по посту 13 первый, так-то предположу сортировку по 3,2,1. А в остальном:

Код: 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.
26.
27.
28.
29.
30.
31.
32.
with t as (
           select  tbl.*,
                   sum(
                       case
                         when col1 = 55 then -1
                         when col1 = 21 then 1
                       end
                      ) over(order by col3,col2,col1) +
                    case col1
                      when 55 then 1
                      else 0
                    end grp
             from  tbl
          )
select  col1,
        col2,
        col3
  from  t
  where grp = 1
  order by col3,
           col2,
           col1
/

      COL1 C       COL3
---------- - ----------
        21 B          1
        14 C          2
        66 D          2
        55 D          3

SQL> 



SY
...
Рейтинг: 0 / 0
Выбор промежуточных значений запросом
    #39368838
stax..
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
arlxstax.., а так?

tt as
(select t.*, sum(decode(a, 55, 1, 0)) over(order by c desc, b desc) o1, sum(decode(a, 14, 1, 0)) over(order by c, b) o2
from t)
select a, b, c, o1, o2
from tt where o1=1 and o2 = 1
order by 3, 2

о вчитался

я б так делал
минусы много сортировок

можно через lag/lead но вырастает вложенность

в 12-ке возможно и через match_recognize

.....
stax
...
Рейтинг: 0 / 0
Выбор промежуточных значений запросом
    #39368846
stax..
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SYleprechaunи будет нужный массив.

У тебя "таблица, на лету отсортированная ORDER BY 3, 2 колонкам" а диапазон по колонке 1. Так-что верхняя грaница 55 может быть раньше нижней 21. Что тогда? И что если верхняя/нижняя грaница встречается несколько раз? И что если верхняя/нижняя грaница нe встречается? Сортировка по 3,2 неднозначна. У тебя две стоки с одинаковыми 3,2:

13, B, 1
21, B, 1

посeму неoпределено идeт ли 13 первым или 21. Судя по посту 13 первый, так-то предположу сортировку по 3,2,1. А в остальном:

Код: 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.
26.
27.
28.
29.
30.
31.
32.
with t as (
           select  tbl.*,
                   sum(
                       case
                         when col1 = 55 then -1
                         when col1 = 21 then 1
                       end
                      ) over(order by col3,col2,col1) +
                    case col1
                      when 55 then 1
                      else 0
                    end grp
             from  tbl
          )
select  col1,
        col2,
        col3
  from  t
  where grp = 1
  order by col3,
           col2,
           col1
/

      COL1 C       COL3
---------- - ----------
        21 B          1
        14 C          2
        66 D          2
        55 D          3

SQL> 



SY

я об
+case col1
when 55 then 1
else 0
end
не догадался
......
stax
...
Рейтинг: 0 / 0
Выбор промежуточных значений запросом
    #39368854
Фотография SY
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
stax..в 12-ке возможно и через match_recognize


Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
select  col1,
        col2,
        col3
  from  tbl
  match_recognize(
                  order by col3,col2,col1
                  all rows per match
                  pattern(up+)
                  define
                      up as first(up.col1) = 21 and prev(up.col1) != 55
                 )
/

      COL1 C       COL3
---------- - ----------
        21 B          1
        14 C          2
        66 D          2
        55 D          3

SQL> 



SY.
...
Рейтинг: 0 / 0
Выбор промежуточных значений запросом
    #39368891
Фотография SeaGate
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SY,

SY
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
select  col1,
        col2,
        col3
  from  tbl
  match_recognize(
                  order by col3,col2,col1
                  all rows per match
                  pattern(up+)
                  define
                      up as first(up.col1) = 21 and prev(up.col1) != 55
                 )
/

      COL1 C       COL3
---------- - ----------
        21 B          1
        14 C          2
        66 D          2
        55 D          3

SQL> 



Это на случай, когда 55 строго есть, как я вижу.
Имеется определенная магия исходных данных в предоставленном ответе.
Просто мой исходный корректно отработает, когда нет 55, или 2х21/1х55 и т.д., но он деревянный, конечно, до красивого с аналитикой не сообразил.
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
with t(a,b,c) as (
select 10, 'A', 1 from dual union all
select 13, 'B', 1 from dual union all
select 21, 'B', 1 from dual union all
select 14, 'C', 2 from dual union all
select 66, 'D', 2 from dual union all
--select 55, 'D', 3 from dual union all
select 24, 'F', 3 from dual union all
select 11, 'E', 3 from dual)
select  a,
        b,
        c
  from  t
  match_recognize(
                  order by c,b,a
                  all rows per match
                  pattern(up+)
                  define
                      up as first(up.a) = 21 and prev(up.a) != 55
                 )
...
Рейтинг: 0 / 0
Выбор промежуточных значений запросом
    #39368900
leprechaun
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Ого набросали вариантов, спасибо друзья, пока вчитываюсь.
...
Рейтинг: 0 / 0
Выбор промежуточных значений запросом
    #39368912
leprechaun
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Я вообще не знаю этих выражений, надо почитать, но код

select col1,
col2,
col3
from tbl
match_recognize(
order by col3,col2,col1
all rows per match
pattern(up+)
define
up as first(up.col1) = 21 and prev(up.col1) != 55)

прекрасно справляется с моей задачей, огромное спасибо! И всем участникам обсуждения также.
...
Рейтинг: 0 / 0
Выбор промежуточных значений запросом
    #39368954
leprechaun
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
еще осталось сообразить как туда также красиво nvl вставить

up as first(up.col1) = 21 and prev(up.col1) != 55)

если 21 и 55 вообще не переданы, чтобы всё вывело
...
Рейтинг: 0 / 0
Выбор промежуточных значений запросом
    #39368972
Фотография SY
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SeaGateИмеется определенная магия исходных данных в предоставленном ответе.


Я ведь все эти вопросы задавaл:

SYУ тебя "таблица, на лету отсортированная ORDER BY 3, 2 колонкам" а диапазон по колонке 1. Так-что верхняя грaница 55 может быть раньше нижней 21. Что тогда? И что если верхняя/нижняя грaница встречается несколько раз? И что если верхняя/нижняя грaница нe встречается? Сортировка по 3,2 неднозначна. У тебя две стоки с одинаковыми 3,2:

13, B, 1
21, B, 1

посeму неoпределено идeт ли 13 первым или 21. Судя по посту 13 первый, так-то предположу сортировку по 3,2,1. А в остальном...


SY.
...
Рейтинг: 0 / 0
Выбор промежуточных значений запросом
    #39368996
Фотография SY
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
leprechaunеще осталось сообразить как туда также красиво nvl вставить


Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
with x as (
           select  t.*,
                   count(case col1 when 21 then 1 end) over() lower_bound_flag
             from  t
          )
select  col1,
        col2,
        col3
  from  x
  match_recognize(
                  order by col3,col2,col1
                  all rows per match
                  pattern(up+)
                  define
                      up as match_number() = 1 and (first(col1) = 21 or lower_bound_flag = 0) and (nvl(prev(col1),0) != 55)
                 )
/




Код: 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.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
SQL> with t as (
  2             select 10 col1,'A' col2,1 col3 from dual union all
  3             select 13,'B',1 from dual union all
  4             select 21,'B',1 from dual union all
  5             select 14,'C',2 from dual union all
  6             select 66,'D',2 from dual union all
  7             select 55,'D',3 from dual union all
  8             select 24,'F',3 from dual union all
  9             select 11,'E',3 from dual
 10            ),
 11       x as (
 12             select  t.*,
 13                     count(case col1 when 21 then 1 end) over() lower_bound_flag
 14               from  t
 15            )
 16  select  col1,
 17          col2,
 18          col3
 19    from  x
 20    match_recognize(
 21                    order by col3,col2,col1
 22                    all rows per match
 23                    pattern(up+)
 24                    define
 25                        up as match_number() = 1 and (first(col1) = 21 or lower_bound_flag = 0) and (nvl(prev(col1),0) != 55)
 26                   )
 27  /

      COL1 C       COL3
---------- - ----------
        21 B          1
        14 C          2
        66 D          2
        55 D          3

SQL> with t as (
  2             select 10 col1,'A' col2,1 col3 from dual union all
  3             select 13,'B',1 from dual union all
  4             select 21,'B',1 from dual union all
  5             select 14,'C',2 from dual union all
  6             select 66,'D',2 from dual union all
  7             select 99,'D',3 from dual union all
  8             select 24,'F',3 from dual union all
  9             select 11,'E',3 from dual
 10            ),
 11       x as (
 12             select  t.*,
 13                     count(case col1 when 21 then 1 end) over() lower_bound_flag
 14               from  t
 15            )
 16  select  col1,
 17          col2,
 18          col3
 19    from  x
 20    match_recognize(
 21                    order by col3,col2,col1
 22                    all rows per match
 23                    pattern(up+)
 24                    define
 25                        up as match_number() = 1 and (first(col1) = 21 or lower_bound_flag = 0) and (nvl(prev(col1),0) != 55)
 26                   )
 27  /

      COL1 C       COL3
---------- - ----------
        21 B          1
        14 C          2
        66 D          2
        99 D          3
        11 E          3
        24 F          3

6 rows selected.

SQL> with t as (
  2             select 10 col1,'A' col2,1 col3 from dual union all
  3             select 13,'B',1 from dual union all
  4             select 77,'B',1 from dual union all
  5             select 14,'C',2 from dual union all
  6             select 66,'D',2 from dual union all
  7             select 55,'D',3 from dual union all
  8             select 24,'F',3 from dual union all
  9             select 11,'E',3 from dual
 10            ),
 11       x as (
 12             select  t.*,
 13                     count(case col1 when 21 then 1 end) over() lower_bound_flag
 14               from  t
 15            )
 16  select  col1,
 17          col2,
 18          col3
 19    from  x
 20    match_recognize(
 21                    order by col3,col2,col1
 22                    all rows per match
 23                    pattern(up+)
 24                    define
 25                        up as match_number() = 1 and (first(col1) = 21 or lower_bound_flag = 0) and (nvl(prev(col1),0) != 55)
 26                   )
 27  /

      COL1 C       COL3
---------- - ----------
        10 A          1
        13 B          1
        77 B          1
        14 C          2
        66 D          2
        55 D          3

6 rows selected.

SQL> with t as (
  2             select 10 col1,'A' col2,1 col3 from dual union all
  3             select 13,'B',1 from dual union all
  4             select 77,'B',1 from dual union all
  5             select 14,'C',2 from dual union all
  6             select 66,'D',2 from dual union all
  7             select 99,'D',3 from dual union all
  8             select 24,'F',3 from dual union all
  9             select 11,'E',3 from dual
 10            ),
 11       x as (
 12             select  t.*,
 13                     count(case col1 when 21 then 1 end) over() lower_bound_flag
 14               from  t
 15            )
 16  select  col1,
 17          col2,
 18          col3
 19    from  x
 20    match_recognize(
 21                    order by col3,col2,col1
 22                    all rows per match
 23                    pattern(up+)
 24                    define
 25                        up as match_number() = 1 and (first(col1) = 21 or lower_bound_flag = 0) and (nvl(prev(col1),0) != 55)
 26                   )
 27  /

      COL1 C       COL3
---------- - ----------
        10 A          1
        13 B          1
        77 B          1
        14 C          2
        66 D          2
        99 D          3
        11 E          3
        24 F          3

8 rows selected.

SQL>  



SY.
...
Рейтинг: 0 / 0
Выбор промежуточных значений запросом
    #39370851
leprechaun
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Уважаемый SY, можете еще немного пояснить.

Вот реальный запрос

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
 
      SELECT ..., t1.* FROM t1
      WHERE ...
      --Условие на организации
      AND t1.org_id IN (
			select organization_id from(
			select organization_id,
				name,
				short_code,
				set_of_books_id
			from  hr_operating_units
			match_recognize(
            order by set_of_books_id,short_code,organization_id
            all rows per match
            pattern(up+)
            define
            --1.Сверху отрезать (кривой код)
            up as first(up.organization_id) = nvl(:P_ORG_FROM, (select organization_id from (select rownum str_number, organization_id from (select organization_id from hr_operating_units order by set_of_books_id, short_code)) where str_number = 2))
            --2.Снизу отрезать
            and prev(up.organization_id) != nvl(:P_ORG_TO, 0))
            ))



Там где нужно снизу отрезать, всё работает, если P_ORG_FROM IS NULL, то 0 дает весь список до конца.
А вот там где нужно сверху отрезать, если я передаю первое по порядку значение, то выдается пустой список. Если передаю второе, то выводится начиная с него.

Я не сильно понял конструкцию со временной таблицей, пришлось фигню временно написать с str_number = 2, так что первое не работает.
Может видя этот запрос еще раз посоветуете как переписать срез сверху с NVL, пробовал читать синтиксис о паттернах, но сходу не въехал.

Спасибо.
...
Рейтинг: 0 / 0
Выбор промежуточных значений запросом
    #39371272
Фотография SY
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
leprechaun,

Ты прaвила уточни. Есть :P_ORG_FROM и :P_ORG_TO:

1. Существуют organization_id с :P_ORG_FROM и :P_ORG_TO - Вывести все organization_id между :P_ORG_FROM и :P_ORG_TO из строк отсортированных по set_of_books_id,short_code,organization_id.

2. Существуeт только organization_id с :P_ORG_FROM (это включает в себя :P_ORG_TO IS NULL) - Вывести все organization_id начиная с :P_ORG_FROM и до конца из строк отсортированных по set_of_books_id,short_code,organization_id.

3. Существуeт только organization_id с :P_ORG_TO (это включает в себя :P_ORG_FROM IS NULL) - Вывести все organization_id между начиная с первой до (включительно) :P_ORG_TO из строк отсортированных по set_of_books_id,short_code,organization_id.

4. Не существуют organization_id с :P_ORG_FROM и :P_ORG_TO (это включает в себя :P_ORG_FROM IS NULL и :P_ORG_TO IS NULL) - Вывести все organization_id отсортированныe по set_of_books_id,short_code,organization_id.

Если да, то:

Код: 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.
26.
27.
28.
29.
      and t1.org_id IN (
                        with x as (
                                   select  t.*,
                                           count(case organization_id when :P_ORG_FROM then 1 end) over() lower_bound_flag
                                     from  hr_operating_units t
                                  )
                        select  organization_id
                          from  t
                          match_recognize(
                                          order by set_of_books_id,short_code,organization_id
                                          all rows per match
                                          pattern(up+)
                                          define
                                            up as     match_number() = 1
                                                  and (
                                                          first(organization_id) = :P_ORG_FROM
                                                       or
                                                          lower_bound_flag = 0
                                                      )
                                                  and 
                                                      nvl(
                                                          prev(organization_id),
                                                          0
                                                         ) != nvl(
                                                                  :P_ORG_TO,
                                                                  -1
                                                                 )
                                         )
                       )



SY.
...
Рейтинг: 0 / 0
Выбор промежуточных значений запросом
    #39371284
Фотография SY
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Хотя тут напрашивается:

Код: 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.
26.
27.
28.
29.
30.
31.
32.
33.
      and (
              (
                   :P_ORG_FROM is null
               and
                   :P_ORG_TO is null
              )
           or t1.org_id IN (
                            with x as (
                                       select  t.*,
                                               count(case organization_id when :P_ORG_FROM then 1 end) over() lower_bound_flag
                                         from  hr_operating_units t
                                      )
                            select  organization_id
                              from  t
                              match_recognize(
                                              order by set_of_books_id,short_code,organization_id
                                              all rows per match
                                              pattern(up+)
                                              define
                                                up as     match_number() = 1
                                                      and (
                                                              first(organization_id) = :P_ORG_FROM
                                                           or
                                                              lower_bound_flag = 0
                                                          )
                                                      and 
                                                          nvl(
                                                              prev(organization_id),
                                                              0
                                                             ) != :P_ORG_TO
                                             )
                           )
          )



SY.
...
Рейтинг: 0 / 0
Выбор промежуточных значений запросом
    #39371391
leprechaun
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Не работает что-то..

еще раз, такой кусок работает без проблем, но если P_ORG_FROM - первая запись отсортированной таблицы, то данных нет

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
     
     select organization_id from(
      select organization_id,
          name,
          short_code,
          set_of_books_id
      from  hr_operating_units
      match_recognize(
            order by set_of_books_id,short_code,organization_id
            all rows per match
            pattern(up+)
            define
            up as first(up.organization_id) = nvl(:P_ORG_FROM, (select organization_id from (select rownum str_number, organization_id from (select organization_id from hr_operating_units order by set_of_books_id, short_code)) where str_number = 2))
            and prev(up.organization_id) != nvl(:P_ORG_TO, 0))
            )



приведенный вами код пытаюсь запустить

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
select organization_id from(
  (WITH x AS (SELECT t.*, COUNT(CASE organization_id WHEN :P_ORG_FROM THEN 1 END) over() lower_bound_flag FROM hr_operating_units t)
    SELECT organization_id FROM x  -- тут только поправил имя таблицы
    match_recognize(ORDER BY set_of_books_id,short_code,organization_id ALL rows per MATCH 
    pattern(up+)
    define 
    up AS match_number() = 1
    AND (FIRST(organization_id) = :P_ORG_FROM OR lower_bound_flag      = 0) AND NVL( prev(organization_id), 0 ) != NVL( :P_ORG_TO, -1 ))
    ))



ORA-00932: несовместимые типы данных: ожидается NUMBER, получено CHAR

Передаю разумеется число. Что еще нужно поправить? Спасибо!
...
Рейтинг: 0 / 0
Выбор промежуточных значений запросом
    #39371427
Фотография SY
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
leprechaunORA-00932: несовместимые типы данных: ожидается NUMBER, получено CHAR


Где? На какой строке? Покажи выолнение в SQL*Plus.

Код: 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.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
160.
161.
162.
163.
164.
165.
166.
167.
168.
169.
170.
171.
172.
173.
174.
175.
176.
177.
178.
179.
180.
181.
182.
183.
184.
185.
186.
187.
188.
189.
190.
SQL> select  *
  2    from  hr_operating_units
  3  /

ORGANIZATION_ID S SET_OF_BOOKS_ID
--------------- - ---------------
             10 A               1
             13 B               1
             21 B               1
             14 C               2
             66 D               2
             55 D               3
             24 F               3
             11 E               3

8 rows selected.

SQL> variable P_ORG_FROM number
SQL> variable P_ORG_TO number
SQL> with x as (
  2             select  t.*,
  3                     count(case organization_id when :P_ORG_FROM then 1 end) over() lower_bound_flag
  4               from  hr_operating_units t
  5            )
  6  select  organization_id
  7    from  x
  8    match_recognize(
  9                    order by set_of_books_id,short_code,organization_id
 10                    all rows per match
 11                    pattern(up+)
 12                    define
 13                      up as     match_number() = 1
 14                            and (
 15                                    first(organization_id) = :P_ORG_FROM
 16                                 or
 17                                    lower_bound_flag = 0
 18                                )
 19                            and 
 20                                nvl(
 21                                    prev(organization_id),
 22                                    0
 23                                   ) != nvl(
 24                                            :P_ORG_TO,
 25                                            -1
 26                                           )
 27                   )
 28  /

ORGANIZATION_ID
---------------
             10
             13
             21
             14
             66
             55
             11
             24

8 rows selected.

SQL> exec :P_ORG_FROM := 21

PL/SQL procedure successfully completed.

SQL> with x as (
  2             select  t.*,
  3                     count(case organization_id when :P_ORG_FROM then 1 end) over() lower_bound_flag
  4               from  hr_operating_units t
  5            )
  6  select  organization_id
  7    from  x
  8    match_recognize(
  9                    order by set_of_books_id,short_code,organization_id
 10                    all rows per match
 11                    pattern(up+)
 12                    define
 13                      up as     match_number() = 1
 14                            and (
 15                                    first(organization_id) = :P_ORG_FROM
 16                                 or
 17                                    lower_bound_flag = 0
 18                                )
 19                            and 
 20                                nvl(
 21                                    prev(organization_id),
 22                                    0
 23                                   ) != nvl(
 24                                            :P_ORG_TO,
 25                                            -1
 26                                           )
 27                   )
 28  /

ORGANIZATION_ID
---------------
             21
             14
             66
             55
             11
             24

6 rows selected.

SQL> exec :P_ORG_TO := 55;

PL/SQL procedure successfully completed.

SQL> with x as (
  2             select  t.*,
  3                     count(case organization_id when :P_ORG_FROM then 1 end) over() lower_bound_flag
  4               from  hr_operating_units t
  5            )
  6  select  organization_id
  7    from  x
  8    match_recognize(
  9                    order by set_of_books_id,short_code,organization_id
 10                    all rows per match
 11                    pattern(up+)
 12                    define
 13                      up as     match_number() = 1
 14                            and (
 15                                    first(organization_id) = :P_ORG_FROM
 16                                 or
 17                                    lower_bound_flag = 0
 18                                )
 19                            and 
 20                                nvl(
 21                                    prev(organization_id),
 22                                    0
 23                                   ) != nvl(
 24                                            :P_ORG_TO,
 25                                            -1
 26                                           )
 27                   )
 28  /

ORGANIZATION_ID
---------------
             21
             14
             66
             55

SQL> exec :P_ORG_FROM := null

PL/SQL procedure successfully completed.

SQL> with x as (
  2             select  t.*,
  3                     count(case organization_id when :P_ORG_FROM then 1 end) over() lower_bound_flag
  4               from  hr_operating_units t
  5            )
  6  select  organization_id
  7    from  x
  8    match_recognize(
  9                    order by set_of_books_id,short_code,organization_id
 10                    all rows per match
 11                    pattern(up+)
 12                    define
 13                      up as     match_number() = 1
 14                            and (
 15                                    first(organization_id) = :P_ORG_FROM
 16                                 or
 17                                    lower_bound_flag = 0
 18                                )
 19                            and 
 20                                nvl(
 21                                    prev(organization_id),
 22                                    0
 23                                   ) != nvl(
 24                                            :P_ORG_TO,
 25                                            -1
 26                                           )
 27                   )
 28  /

ORGANIZATION_ID
---------------
             10
             13
             21
             14
             66
             55

6 rows selected.

SQL> 



SY.
...
Рейтинг: 0 / 0
Выбор промежуточных значений запросом
    #39371815
leprechaun
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Хм.. стыдно сказать SQL*Plus не установлен, удаленно через последний SQL Developer делаю.
Может и в оболочке проблема.
Но вставил этот код как условие для внешнего запроса - выдало ORA-32034: не поддерживается использование фразы WITH
А в девелопере не выполняется временная таблица

select t.*, count(case organization_id when :P_ORG_FROM then 1 end) over() lower_bound_flag from hr_operating_units t

ORA-00932: несовместимые типы данных: ожидается NUMBER, получено CHAR
P_ORG_FROM передаю число.
...
Рейтинг: 0 / 0
Выбор промежуточных значений запросом
    #39371844
leprechaun
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Поставил пока костыль, т.к. время поджимает

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
     select organization_id from(
        (select organization_id, name, short_code, set_of_books_id
         from hr_operating_units
         --временный костыль
         union all
         select * from
         (select organization_id, name, short_code, set_of_books_id
         from hr_operating_units
         order by set_of_books_id, short_code)
         where rownum =1)
      match_recognize(
            order by set_of_books_id,short_code,organization_id
            all rows per match
            pattern(up+)
            define
            up as first(up.organization_id) = nvl(:P_ORG_FROM, (select * from (select organization_id from hr_operating_units order by set_of_books_id, short_code) where rownum = 1))
            and prev(up.organization_id) != nvl(:P_ORG_TO, 0))
            )



В любом случае спасибо огромное за помощь!
...
Рейтинг: 0 / 0
Выбор промежуточных значений запросом
    #39371975
leprechaun
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
+ И да, еще эта конструкция выводит пустой список, если :P_ORG_TO - первое значение в отсортированной таблице. Далее нормально.
...
Рейтинг: 0 / 0
32 сообщений из 32, показаны все 2 страниц
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Выбор промежуточных значений запросом
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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