расширенный выбор в хранимой процедуре - PullRequest
1 голос
/ 27 апреля 2010

я получил эту таблицу:

CREATE TABLE Test_Table (
    old_val VARCHAR2(3),
    new_val VARCHAR2(3),
    Updflag NUMBER,
    WorkNo NUMBER  );

и это в моей таблице:

INSERT INTO Test_Table  (old_val, new_val, Updflag , WorkNo) VALUES('1',' 20',0,0);
INSERT INTO Test_Table  (old_val, new_val, Updflag , WorkNo) VALUES('2',' 20',0,0);
INSERT INTO Test_Table  (old_val, new_val, Updflag , WorkNo) VALUES('2',' 30',0,0);
INSERT INTO Test_Table  (old_val, new_val, Updflag , WorkNo) VALUES('3',' 30',0,0);    
INSERT INTO Test_Table  (old_val, new_val, Updflag , WorkNo) VALUES('4',' 40',0,0);
INSERT INTO Test_Table  (old_val, new_val, Updflag , WorkNo) VALUES('4',' 40',0,0);

теперь мой стол выглядит так:

Row  Old_val  New_val       Updflag  WorkNo
1    '1'        ' 20'       0        0
2    '2'        ' 20'       0        0
3    '2'        ' 30'       0        0
4    '3'        ' 30'       0        0
5    '4'        ' 40'       0        0
6    '5'        ' 40'       0        0

(если значения в столбце new_val совпадают, то они вместе и то же самое переходит к old_val) поэтому в приведенном выше примере строки 1-4 вместе и строка 5-6

на данный момент в моей хранимой процедуре есть курсор:

 SELECT t1.Old_val, t1.New_val, t1.updflag, t1.WorkNo
    FROM Test_Table t1
    WHERE t1.New_val =
      (
        SELECT t2.New_val
        FROM Test_Table t2
        WHERE t2.Updflag = 0
          AND t2.Worknr = 0
          AND ROWNUM = 1
      )

вывод такой:

Row  Old_val  New_val   Updflag  WorkNo
1    1         20       0        0
2    2         20       0        0

Моя проблема в том, что я не знаю, как получить строки с 1 по 4 одним выбором. (у меня была идея с 4 подзапросами, но это не сработает, если их больше данных, которые совпадают вместе)

у кого-нибудь из вас есть идея?

Ответы [ 2 ]

1 голос
/ 27 апреля 2010

вы можете использовать аналитику для определения групп смежных строк:

SQL> SELECT old_val, new_val, updflag, workno,
  2         SUM(gap) over(ORDER BY old_val, new_val) grp
  3    FROM (SELECT t.*,
  4                  CASE
  5                     WHEN new_val = lag(new_val)
  6                                    over(ORDER BY old_val, new_val)
  7                       OR old_val = lag(old_val)
  8                                    over(ORDER BY old_val, new_val)
  9                     THEN
 10                      0
 11                     ELSE
 12                      1
 13                  END gap
 14             FROM Test_Table t);

OLD_VAL NEW_VAL    UPDFLAG     WORKNO        GRP
------- ------- ---------- ---------- ----------
1        20              0          0          1
2        20              0          0          1
2        30              0          0          1
3        30              0          0          1
4        40              0          0          2
4        40              0          0          2

Внутренний SELECT создает столбец «GAP», который равен 1, когда текущая строка не входит в ту же группу, что и предыдущая.

Внешний SELECT использует промежуточный итог по столбцу пропуска для получения номера группы.

Редактировать 2

Невозможно добавить предложение FOR UPDATE непосредственно в запрос из-за аналитических функций. Вы можете напрямую запросить базовую таблицу:

SQL> WITH t_new AS (
  2  SELECT t_rowid, old_val, new_val, updflag, workno,
  3         SUM(gap) over(ORDER BY old_val, new_val) grp
  4    FROM (SELECT t.*, t.rowid t_rowid,
  5                  CASE
  6                     WHEN new_val = lag(new_val)
  7                                    over(ORDER BY old_val, new_val)
  8                       OR old_val = lag(old_val)
  9                                    over(ORDER BY old_val, new_val)
 10                     THEN
 11                      0
 12                     ELSE
 13                      1
 14                  END gap
 15             FROM test_table t)
 16  )
 17  SELECT *
 18    FROM test_table
 19   WHERE ROWID IN (SELECT t_rowid
 20                     FROM t_new
 21                    WHERE grp = (SELECT grp
 22                                   FROM t_new t2
 23                                  WHERE t2.new_val = ' 20'
 24                                    AND t2.old_val = '1'))
 25     FOR UPDATE;

OLD_VAL NEW_VAL    UPDFLAG     WORKNO
------- ------- ---------- ----------
1        20              0          0
2        20              0          0
2        30              0          0
3        30              0          0
0 голосов
/ 27 апреля 2010

Если вам нужны все строки, которые «вместе с чем-то» возвращены, то не похоже, что ваши исходные данные примера предоставляют строку, которую не следует возвращать. Итак, добавим следующее:

INSERT INTO Test_Table  (old_val, new_val, Updflag , WorkNo) VALUES('6',' 50',0,0);

Этот ряд не должен быть ни с чем и не должен быть возвращен. Учитывая это, я думаю, что мы можем использовать EXISTS, чтобы получить то, что вы хотите:

Select *
From Test_Table T1
Where Exists    (
                Select 1
                From Test_Table T2
                Where ( T2.old_val = T1.old_val Or T2.new_val = T1.new_val )
                    And ( T2.row <> T1.row )
                )
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...