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

Сейчас она в таком виде:
BDate DB CR BALANCE

11-01-2016 0 1000 1000
25-01-2016 500 400 900
08-02-2016 300 0 600

А нужно :

01-01-2016 0 0 0
02-01-2016 0 0 0
........
11-01-2016 0 1000 1000
12-01-2016 0 0 1000
.......
25-01-2016 500 400 900
26-01-2016 0 0 900
.......
01-02-2016 0 0 900
..........
08-02-2016 300 0 600
.....
28-02-2016 0 0 600
и т.д.
т.е её необходимо дополнить полными месяцами и остатком на каждый день , сейчас записи имеются только для вариантов, когда были движения по счёту.

Я нашел вариант для MS-SQL, но не смог переработать для Oracle в силу нехватки знаний.
http://www.sql.ru/forum/1178550/srednehronologicheskiy-ostatok-dobavlenie-iskusstvenno-predydushhih-znacheniy
...
Рейтинг: 0 / 0
Добавить селектом недостающие значения
    #39332602
Alexls
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
SELECTOM скорее всего никак. А вот с помощью MERGE вполне
...
Рейтинг: 0 / 0
Добавить селектом недостающие значения
    #39332605
Esploratore
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
К ,сожалению, править таблицу нельзя
...
Рейтинг: 0 / 0
Добавить селектом недостающие значения
    #39332609
Alexls
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Так куда вам нужно добавить в таблицу или в выборку
...
Рейтинг: 0 / 0
Добавить селектом недостающие значения
    #39332615
Esploratore
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
В выборку
...
Рейтинг: 0 / 0
Добавить селектом недостающие значения
    #39332617
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Значит тебе нужен источник "всех значений", с которым ты и будешь делать outer join своей
таблицы.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Добавить селектом недостающие значения
    #39332619
Avotge
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
with? self join?
Смотря по какому принципу надо добавлять, по тестовым данным не очень понятно.
...
Рейтинг: 0 / 0
Добавить селектом недостающие значения
    #39332621
Avotge
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Esploratoreт.е её необходимо дополнить полными месяцами и остатком на каждый день , сейчас записи имеются только для вариантов, когда были движения по счёту.
Поискать что-то вроде start of group?
...
Рейтинг: 0 / 0
Добавить селектом недостающие значения
    #39332626
Esploratore
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
CREATE TABLE BALANCES
(ID NUMBER NOT NULL,
ACCT_ID NUMBER NOT NULL,
BDATE DATE NOT NULL,
CR NUMBER (20,2),
DB NUMBER (20,2),
BALANCE NUMBER (20,2));

INSERT INTO BALANCES VALUES (1, 1, TO_DATE('15-01-2016','DD-MM-YYYY'), 1000.00, 0.00, 1000.00);
INSERT INTO BALANCES VALUES (2, 1, TO_DATE('22-01-2016','DD-MM-YYYY'), 600.00, 300.00, 1300.00);
INSERT INTO BALANCES VALUES (3, 1, TO_DATE('04-02-2016','DD-MM-YYYY'), 100.00, 0.00, 1400.00);
INSERT INTO BALANCES VALUES (4, 1, TO_DATE('29-02-2016','DD-MM-YYYY'), 0.00, 200.00, 1200.00);

Вот данные для таблицы
...
Рейтинг: 0 / 0
Добавить селектом недостающие значения
    #39332630
Alexls
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Проще всего сделать на клиенте.
А так навскидку два варианта

a.
1. select из основной таблицы в tmp
2. MEGRGE в тмп таблицу
3. выборка

2. более сложный
1. Сформировать список дат со значениями
2. UNION с основной выборкой
...
Рейтинг: 0 / 0
Добавить селектом недостающие значения
    #39332633
Zloxa
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Esploratoreнеобходимо дополнить полными месяцами и остатком на каждый день , сейчас записи имеются только для вариантов, когда были движения по счёту.

Use of Partition Outer Join to Handle Sparse Data
+
LAST_VALUE analytic function
...
Рейтинг: 0 / 0
Добавить селектом недостающие значения
    #39332697
Avotge
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
А вдруг это оно )
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
WITH t1 AS (SELECT TO_DATE('11-01-2016', 'dd.mm.yyyy') dt, 0 db, 1000 cr, 1000 balance FROM dual
             UNION ALL
            SELECT TO_DATE('25-01-2016', 'dd.mm.yyyy') dt, 500 db, 400 cr, 800 balance FROM dual
             UNION ALL
            SELECT TO_DATE('08-02-2016', 'dd.mm.yyyy') dt, 300 db, 0 cr, 500 balance FROM dual),
     t2 AS (SELECT TO_DATE('10-01-2016', 'dd.mm.yyyy') + LEVEL dt
              FROM dual
           CONNECT BY LEVEL < 50)
SELECT t2.dt, 
       NVL(t1.db, 0) db,
       NVL(t1.cr, 0) cr,
       NVL2(t1.balance, t1.balance,
            (SELECT MAX(t.balance) KEEP(DENSE_RANK LAST ORDER BY t.dt)
              FROM t1 t
             WHERE t.balance IS NOT NULL 
               AND t.dt < t2.dt)
            ) balance,
       t1.balance source_balance
  FROM t2, t1
 WHERE t2.dt = t1.dt(+)
 ORDER BY t2.dt

...
Рейтинг: 0 / 0
Добавить селектом недостающие значения
    #39332901
Futbolist
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Вариант с last_value, но без partition outer join

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
with per as (
  select trunc(min(bdate), 'month') strt,
  last_day(max(bdate)) fin,
  min(balance-cr+db) keep (DENSE_RANK FIRST ORDER BY bdate) start_bal -- остаток на последний день предыдущего месяца
  from BALANCES
),
dates as (
select strt + level - 1 bdate
from per 
connect by level < fin - strt + 2
),
date_bal as (
  select d.bdate from dates d
)
select d.bdate, nvl(b.cr, 0), nvl(b.db,0), nvl(last_value(b.balance) ignore nulls over (order by d.bdate), per.start_bal) balance,  per.start_bal
from date_bal d
left join balances b
on b.bdate = d.bdate
cross join per
order by bdate
...
Рейтинг: 0 / 0
Добавить селектом недостающие значения
    #39332903
Futbolist
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Futbolist,

Лучше так - было лишнее cte.

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
with per as (
  select trunc(min(bdate), 'month') strt,
  last_day(max(bdate)) fin,
  min(balance-cr+db) keep (DENSE_RANK FIRST ORDER BY bdate) start_bal -- остаток на последний день предыдущего месяца
  from BALANCES
),
dates as (
select strt + level - 1 bdate
from per 
connect by level < fin - strt + 2
)
select d.bdate, nvl(b.cr, 0), nvl(b.db,0), nvl(last_value(b.balance) ignore nulls over (order by d.bdate), per.start_bal) balance,  per.start_bal
from dates d
left join balances b
on b.bdate = d.bdate
cross join per
order by bdate
...
Рейтинг: 0 / 0
Добавить селектом недостающие значения
    #39332954
Joker_Ya1
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Получить все дни в диапазоне без пропусков ну и затем получить в данный день сумму баланса не составит труда.
SELECT date_b + level from dual
connect by level < (date_e - date_b)
...
Рейтинг: 0 / 0
Добавить селектом недостающие значения
    #39333073
Esploratore
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Futbolist - спасибо огромное !

Только еще я забыл одно условие - вывести acct_id в итоговой выборке, как это можно сделать ?
...
Рейтинг: 0 / 0
Добавить селектом недостающие значения
    #39333192
Futbolist
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Esploratore,

авторТолько еще я забыл одно условие - вывести acct_id в итоговой выборке, как это можно сделать ?


Если acct_id разные и для каждого для каждой даты должны быть свои строки с дебетом и кредитом (нулевыми, если движений не было) и остатком на дату, все немного усложняется. Надо вводить группировку по счетам и в last_value будет partition by

Код: 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 BALANCES
(ID NUMBER NOT NULL,
ACCT_ID NUMBER NOT NULL,
BDATE DATE NOT NULL,
CR NUMBER (20,2),
DB NUMBER (20,2),
BALANCE NUMBER (20,2));

INSERT INTO BALANCES VALUES (1, 1, TO_DATE('15-01-2016','DD-MM-YYYY'), 1000.00, 0.00, 1000.00);
INSERT INTO BALANCES VALUES (2, 1, TO_DATE('22-01-2016','DD-MM-YYYY'), 600.00, 300.00, 1300.00);
INSERT INTO BALANCES VALUES (3, 1, TO_DATE('04-02-2016','DD-MM-YYYY'), 100.00, 0.00, 1400.00);
INSERT INTO BALANCES VALUES (4, 1, TO_DATE('29-02-2016','DD-MM-YYYY'), 0.00, 200.00, 1200.00);

INSERT INTO BALANCES VALUES (5, 2, TO_DATE('12-01-2016','DD-MM-YYYY'), 20.00, 6.00, 14.00);
INSERT INTO BALANCES VALUES (6, 2, TO_DATE('22-01-2016','DD-MM-YYYY'), 100.00, 50.00, 64.00);

-- остаток может быть и до периода - пришло 200, а 300 уже было
INSERT INTO BALANCES VALUES (7, 3, TO_DATE('04-02-2016','DD-MM-YYYY'), 200.00, 0.00, 500.00);
INSERT INTO BALANCES VALUES (8, 3, TO_DATE('05-02-2016','DD-MM-YYYY'), 0.00, 100.00, 400.00);
INSERT INTO BALANCES VALUES (9, 3, TO_DATE('06-02-2016','DD-MM-YYYY'), 200.00, 600.00, 0.00);

INSERT INTO BALANCES VALUES (10, 4, TO_DATE('29-01-2016','DD-MM-YYYY'), 10000.00, 4000.00, 6000.00);
INSERT INTO BALANCES VALUES (11, 4, TO_DATE('04-02-2016','DD-MM-YYYY'), 11111.00, 0.00, 17611.00);

commit;



Код: 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.
-- счета
with per_acc as (
  select 
    acct_id acct_id,
    min(bdate) strt, 
    max(bdate) fin
    from BALANCES
  group by acct_id
),

-- самое первое и самое последнее числа месяца
per as (
  select
    trunc(min(strt), 'month') strt,
    last_day(max(fin)) fin
  from per_acc pa

),

-- счет, остаток на утро начала периода
acc_strt as (
    select 
        pa.acct_id,
        b.balance - b.cr + b.db strt_bal -- остаток на последнее число предыдущего месяца
       from per_acc pa
       inner join balances b
       on b.acct_id = pa.acct_id
       and b.bdate = pa.strt
),

-- все даты в периоде
dates as (
select strt + level - 1 bdate 
from per 
connect by level < fin - strt + 2
)

-- собственно выборка
select 
    acc_st.acct_id,
    d.bdate,
    nvl(b.cr, 0),
    nvl(b.db,0), 
    nvl(last_value(b.balance) ignore nulls over (partition by acc_st.acct_id order by d.bdate), acc_st.strt_bal) balance 

from acc_strt acc_st

cross join dates d

left join balances b
on b.bdate = d.bdate 
and b.acct_id = acc_st.acct_id 

cross join per

order by acc_st.acct_id, d.bdate
...
Рейтинг: 0 / 0
Добавить селектом недостающие значения
    #39333193
Futbolist
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Код: sql
1.
cross join per



можно выкинуть, per теперь используется только в cte. Издержки переработки запроса...
...
Рейтинг: 0 / 0
Добавить селектом недостающие значения
    #39333308
Zloxa
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Futbolist, от чего на твоих данных, баланс, к примеру, по acct_id=3 на 01.01.2016 возвращается вдруг 300 ;)
Все же мне кажется проще - так
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
with 
    dates as 
    (
        select strt + level - 1 bdate
        from (select min(bdate) strt, max(bdate) fin from balances) 
        connect by strt + level - 1 <= fin
    )
select
    d.bdate,
    b.acct_id,
    nvl(b.cr, 0), 
    nvl(b.db, 0), 
    nvl(last_value(b.balance) ignore nulls over (partition by b.acct_id order by d.bdate), 0) balance
from balances b
partition by (b.acct_id) right join dates d on d.bdate = b.bdate


...
Рейтинг: 0 / 0
Добавить селектом недостающие значения
    #39333333
Futbolist
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
авторот чего на твоих данных, баланс, к примеру, по acct_id=3 на 01.01.2016 возвращается вдруг 300 ;)


Ну это попытка получить остатки, если, например, остатки за некий начальный период удалили или селект делается по выборке за период. Там типа не совсем корректное первое значение
Код: plsql
1.
INSERT INTO BALANCES VALUES (7, 3, TO_DATE('04-02-2016','DD-MM-YYYY'), 200.00, 0.00, 500.00);


Был приход 200, а остаток стал не 200, а 500. Вот я и считаю, что 300 было в предыдущий день.

А за пример с PARTITION BY спасибо, не знал про него, как раз сегодня хотел прочитать твою ссылку.
...
Рейтинг: 0 / 0
Добавить селектом недостающие значения
    #39333374
Zloxa
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Futbolistпример с PARTITION BY
Он здесь годен только для случая, если мы не рассчитываем входящий остаток для периода, позволяет избежать явного кроссджойна с distinct по acct_id. При наличии требования включения входящего остатка, у нас необходимость в партишн джойне отпадает, потому как есть набор входящего остатка, к которому кросджойним множетсво дат и джойним слева факты.
...
Рейтинг: 0 / 0
21 сообщений из 21, страница 1 из 1
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Добавить селектом недостающие значения
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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