Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Добавить селектом недостающие значения / 21 сообщений из 21, страница 1 из 1
24.10.2016, 11:29
    #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
24.10.2016, 11:32
    #39332602
Alexls
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Добавить селектом недостающие значения
SELECTOM скорее всего никак. А вот с помощью MERGE вполне
...
Рейтинг: 0 / 0
24.10.2016, 11:35
    #39332605
Esploratore
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Добавить селектом недостающие значения
К ,сожалению, править таблицу нельзя
...
Рейтинг: 0 / 0
24.10.2016, 11:42
    #39332609
Alexls
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Добавить селектом недостающие значения
Так куда вам нужно добавить в таблицу или в выборку
...
Рейтинг: 0 / 0
24.10.2016, 11:50
    #39332615
Esploratore
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Добавить селектом недостающие значения
В выборку
...
Рейтинг: 0 / 0
24.10.2016, 11:52
    #39332617
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Добавить селектом недостающие значения
Значит тебе нужен источник "всех значений", с которым ты и будешь делать outer join своей
таблицы.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
24.10.2016, 11:53
    #39332619
Avotge
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Добавить селектом недостающие значения
with? self join?
Смотря по какому принципу надо добавлять, по тестовым данным не очень понятно.
...
Рейтинг: 0 / 0
24.10.2016, 11:55
    #39332621
Avotge
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Добавить селектом недостающие значения
Esploratoreт.е её необходимо дополнить полными месяцами и остатком на каждый день , сейчас записи имеются только для вариантов, когда были движения по счёту.
Поискать что-то вроде start of group?
...
Рейтинг: 0 / 0
24.10.2016, 11:59
    #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
24.10.2016, 12:02
    #39332630
Alexls
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Добавить селектом недостающие значения
Проще всего сделать на клиенте.
А так навскидку два варианта

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

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

Use of Partition Outer Join to Handle Sparse Data
+
LAST_VALUE analytic function
...
Рейтинг: 0 / 0
24.10.2016, 13:26
    #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
24.10.2016, 15:55
    #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
24.10.2016, 15:59
    #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
24.10.2016, 16:31
    #39332954
Joker_Ya1
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Добавить селектом недостающие значения
Получить все дни в диапазоне без пропусков ну и затем получить в данный день сумму баланса не составит труда.
SELECT date_b + level from dual
connect by level < (date_e - date_b)
...
Рейтинг: 0 / 0
24.10.2016, 18:44
    #39333073
Esploratore
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Добавить селектом недостающие значения
Futbolist - спасибо огромное !

Только еще я забыл одно условие - вывести acct_id в итоговой выборке, как это можно сделать ?
...
Рейтинг: 0 / 0
25.10.2016, 00:01
    #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
25.10.2016, 00:04
    #39333193
Futbolist
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Добавить селектом недостающие значения
Код: sql
1.
cross join per



можно выкинуть, per теперь используется только в cte. Издержки переработки запроса...
...
Рейтинг: 0 / 0
25.10.2016, 10:17
    #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
25.10.2016, 10:39
    #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
25.10.2016, 11:21
    #39333374
Zloxa
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Добавить селектом недостающие значения
Futbolistпример с PARTITION BY
Он здесь годен только для случая, если мы не рассчитываем входящий остаток для периода, позволяет избежать явного кроссджойна с distinct по acct_id. При наличии требования включения входящего остатка, у нас необходимость в партишн джойне отпадает, потому как есть набор входящего остатка, к которому кросджойним множетсво дат и джойним слева факты.
...
Рейтинг: 0 / 0
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Добавить селектом недостающие значения / 21 сообщений из 21, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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