Сохранить растровое изображение в соответствующем столбце - Oracle - PullRequest
2 голосов
/ 22 мая 2019

У меня есть таблица:

table1

id      col     val         rec_pos
1       Test 1  10          1
1       Test 2  20          2
1       Test 3  30          3
1       Test 2  20          4
1       Empty   0101        5
1       Invalid 1011        6

2       Test 4  30          2
2       Test 5  30          3
2       Test 6  30          4
2       Test 5  30          5
2       Empty   11101       6
2       Invalid 10101       7


3       Test 7  30          5
3       Test 8  30          6
3       Test 8  30          7
3       Test 8  30          8
3       Empty   11110101    9
3       Invalid 10010101    10

4       Test 9  30          3
4       Empty   1101        5
4       Invalid 1011        6

Для каждого уникального id мне нужно взять val для col = 'Пусто' и затем использовать rec_pos, добавьте новый столбец с именем empty и добавьте соответствующие значения.

То же самое для недействительных, для каждого уникального id мне нужно взять val для col = 'Invalid', а затем, используя rec_pos, добавить новый столбец с именем invalid и добавитьсоответствующие значения.

Пример:

  1. Для id = 1, col = пусто, val = 0101

    • rec_pos = 1, добавить значение в пустой столбец= 0
    • rec_pos = 2, добавить значение в пустой столбец = 1
    • rec_pos = 3, добавить значение в пустой столбец = 0
    • rec_pos = 4, добавить значение в пустойcolumn = 1
  2. Для id = 4, col = Пусто, val = 1101

    • rec_pos = 1, добавить значение в пустой столбец = 1
    • rec_pos = 2, добавить значение в пустой столбец = 1
    • rec_pos = 3, добавить значение в пустой столбец = 0
    • rec_pos = 4, добавить значение в пустой столбец =1

Вывод будет:

id      col     val         rec_pos     empty       invalid
1       Test 1  10          1           0           1
1       Test 2  20          2           1           0
1       Test 3  30          3           0           1
1       Test 2  20          4           1           1
1       Empty   0101        5           0           0
1       Invalid 1011        6           0           0

2       Test 4  30          2           1           0
2       Test 5  30          3           1           1
2       Test 6  30          4           0           0
2       Test 5  30          5           1           1
2       Empty   11101       6           0           0
2       Invalid 10101       7           0           0


3       Test 7  30          5           0           0
3       Test 8  30          6           1           1
3       Test 8  30          7           0           0
3       Test 8  30          8           1           1
3       Empty   11110101    9           0           0
3       Invalid 10010101    10          0           0

4       Test 9  30          3           0           1
4       Empty   1101        5           0           0
4       Invalid 1011        6           0           0

Как я могу прочитать значения и затем соответствующим образом назначить их соответствующим rec_pos для того же идентификатора?

Ответы [ 3 ]

2 голосов
/ 22 мая 2019

Я думаю, что это дает вам вывод, который вы просили.

SELECT  t.id,
    t.col,
    t.val,
    t.rec_pos,
    NVL(e.empty, 0) AS empty,
    NVL(i.invalid, 0) AS invalid
FROM
    table1 t
LEFT
JOIN    (SELECT DISTINCT t.id, levels.column_value AS rec_pos, SUBSTR(val, levels.column_value, 1) AS empty
     FROM table1 t, TABLE(CAST(MULTISET(SELECT level FROM dual CONNECT BY level <= LENGTH(val)) AS sys.OdciNumberList)) levels
     WHERE t.col = 'Empty' ORDER BY id) e ON e.id = t.id AND e.rec_pos = t.rec_pos
LEFT
JOIN    (SELECT DISTINCT t.id, levels.column_value AS rec_pos, SUBSTR(val, levels.column_value, 1) AS invalid
     FROM table1 t, TABLE(CAST(MULTISET(SELECT level FROM dual CONNECT BY level <= LENGTH(val)) AS sys.OdciNumberList)) levels
     WHERE t.col = 'Invalid' ORDER BY id) i ON i.id = t.id AND i.rec_pos = t.rec_pos
ORDER
BY  t.id, t.rec_pos;
2 голосов
/ 22 мая 2019

Если позиция определяется rec_pos, то вы можете просто использовать susbtr в сочетании с аналитическим max:

select t.*, 
       nvl(substr(max(case col when 'Empty' then val end) 
                     over (partition by id), rec_pos, 1), 0) empty,
       nvl(substr(max(case col when 'Invalid' then val end) 
                     over (partition by id), rec_pos, 1), 0) invalid
  from  table1 t

или с коррелированными подзапросами:

select t.*, 
       nvl(substr((select val 
                    from table1 e 
                    where e.id = t.id and col= 'Empty'), rec_pos, 1), 0) empty,
       nvl(substr((select val 
                    from table1 i 
                    where i.id = t.id and col= 'Invalid'), rec_pos, 1), 0) invalid
  from  table1 t

Демоверсия dbfiddle

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

2 голосов
/ 22 мая 2019

Контрольный пример (только для ID s 1 и 4; не хотелось много печатать):

SQL> create table test
  2    (id       number,
  3     col      varchar2(10),
  4     val      varchar2(10),
  5     rec_pos  number,
  6     empty    number,
  7     invalid  number);

Table created.

SQL> insert into test (id, col, val, rec_pos)
  2    (select 1, 'test 1',  '10'  , 1 from dual union all
  3     select 1, 'test 2' , '20'  , 2 from dual union all
  4     select 1, 'test 3' , '30'  , 3 from dual union all
  5     select 1, 'test 2' , '20'  , 4 from dual union all
  6     select 1, 'empty'  , '0101', 5 from dual union all
  7     select 1, 'invalid', '1011', 6 from dual union all
  8     --
  9     select 4, 'test 9' , '30'  , 3 from dual union all
 10     select 4, 'empty'  , '1101', 5 from dual union all
 11     select 4, 'invalid', '1011', 6 from dual
 12    );

9 rows created.

SQL> select * From test;

        ID COL        VAL           REC_POS      EMPTY    INVALID
---------- ---------- ---------- ---------- ---------- ----------
         1 test 1     10                  1
         1 test 2     20                  2
         1 test 3     30                  3
         1 test 2     20                  4
         1 empty      0101                5
         1 invalid    1011                6
         4 test 9     30                  3
         4 empty      1101                5
         4 invalid    1011                6

9 rows selected.

SQL>

Оператор обновления:

SQL> update test e set
  2    e.empty = (select nvl(x.digit, 0)
  3               from ( select t.id,
  4                             substr(t.val, column_value, 1) digit,
  5                             column_value rec_pos
  6                      from test t join
  7                           table(cast(multiset(select level from dual
  8                                               connect by level <= (select max(t1.rec_pos)
  9                                                                    from test t1
 10                                                                    where t1.id = t.id
 11                                                                   )
 12                                               ) as sys.odcinumberlist ))
 13                           on 1 = 1
 14                      where t.col = 'empty'
 15                     ) x
 16               where x.id = e.id
 17                 and x.rec_pos = e.rec_pos
 18              ),
 19    --
 20    e.invalid = (select nvl(x.digit, 0)
 21                 from ( select t.id,
 22                               substr(t.val, column_value, 1) digit,
 23                               column_value rec_pos
 24                        from test t join
 25                              table(cast(multiset(select level from dual
 26                                                  connect by level <= (select max(t1.rec_pos)
 27                                                                       from test t1
 28                                                                       where t1.id = t.id
 29                                                                      )
 30                                                  ) as sys.odcinumberlist ))
 31                             on 1 = 1
 32                        where t.col = 'invalid'
 33                       ) x
 34                 where x.id = e.id
 35                   and x.rec_pos = e.rec_pos
 36                );

9 rows updated.

SQL>

Что это делает?

  • берет VAL и разбивает его на строки
  • (для SUBSTR) определяется максимальным значением REC_POS для этого ID, чтобы вы могли использовать NVL позже при обновлении столбца EMPTY (или INVALID)
  • в основном, оба обновления равны, они отличаются только чем вы обновляете (строки # 14 и # 32)

Результат:

SQL> select * from test;

        ID COL        VAL           REC_POS      EMPTY    INVALID
---------- ---------- ---------- ---------- ---------- ----------
         1 test 1     10                  1          0          1
         1 test 2     20                  2          1          0
         1 test 3     30                  3          0          1
         1 test 2     20                  4          1          1
         1 empty      0101                5          0          0
         1 invalid    1011                6          0          0
         4 test 9     30                  3          0          1
         4 empty      1101                5          0          0
         4 invalid    1011                6          0          0

9 rows selected.

SQL>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...