powered by simpleCommunicator - 2.0.53     © 2025 Programmizd 02
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Помогите написать JOIN
13 сообщений из 13, страница 1 из 1
Помогите написать JOIN
    #39277195
akrush
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Добрый день.
Помогите правильно написать FULL JOIN.
Имею 2 таблицы, структура и названия полей одинаковые.
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
Code integer - код организации
Numb integer - номер дела
sm1 numeric(9,2) - услуга 1
sm2 numeric(9,2) - услуга 2
sm3 numeric(9,2) - услуга 3
sm4 numeric(9,2) - услуга 4
sm5 numeric(9,2) - услуга 5
sm6 numeric(9,2) - услуга 6
sm7 numeric(9,2) - услуга 7
sm8 numeric(9,2) - услуга 8


Ключевые поля: Code, numb

Таблица 1 содержит первоначальные данные по отчетам.
Таблица 2 Содержит измененные отчеты (так получилось что пришлось изменить отчеты, но так как информация уже отправлена на организации по "таблице1" в текущем месяце нужно внести корректировки относительно "таблица2". Для этого нужно найти разницу "Таблица2"-"Таблица1"

В таблицах может быть от 1 до 3 строчек по ключевым полям и по столбцам sm1-sm8 нужно сделать суммирование.
Я знаю как просуммировать столбцы, но по каждой таблице отдельно:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
select code, numb, sum(sm1), sum(sm2), sum(sm3), sum(sm4), sum(sm5), sum(sm6), sum(sm7), sum(sm8)
from tab1
group by code, numb 

и 

select code, numb, sum(sm1), sum(sm2), sum(sm3), sum(sm4), sum(sm5), sum(sm6), sum(sm7), sum(sm8)
from tab2
group by code, numb 



Как теперь получить разницу между "Таблица_2" минус "Таблица_1". Причем могут быть дела которые присутствуют в "таблице 1", но отсутствуют в "таблице 2" и наоборот, есть в "таблице 2" - отсутствуют в "таблице 1"
Хотелось бы получить что-то пита такого:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
Таблица 1:
code numb sm1     sm2     sm3     sm4     sm5      sm6     sm7     sm8
1      1      0.00     5.00     0.00     0.00     4.00     0.00     0.00     0.00
1      2      0.00     0.00     0.00     0.00     4.00     0.00     0.00     0.00
1      5      5.00     5.00     0.00     0.00     4.00     0.00     0.00     0.00
1      8      0.00     5.00     0.00     -50.00  4.00     0.00     0.00     0.00

Таблица 2:
code numb sm1      sm2      sm3      sm4      sm5      sm6      sm7      sm8
1      2      0.00      0.00      0.00      0.00      4.00      0.00      0.00      0.00
1      5      3.00      8.00      0.00      0.00      9.00      0.00      0.00      0.00
1      9      0.00      5.00      0.00      -50.00   4.00      0.00      0.00      0.00

В ИТОГЕ:
1      1      0.00      -5.00     0.00      0.00      -4.00     0.00      0.00      0.00
1      2      0.00      0.00      0.00      0.00      0.00      0.00      0.00      0.00
1      5      -2.00     3.00      0.00      0.00      5.00      0.00      0.00      0.00
1      8      0.00      -5.00     0.00      50.00     -4.00    0.00      0.00      0.00
1      9      0.00      5.00      0.00      -50.00    4.00     0.00      0.00      0.00



Firebird 2.5
...
Рейтинг: 0 / 0
Помогите написать JOIN
    #39277200
akrush
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ну или получить что-то такого вида, с суммированием полей SM
Code1, numb1, sm1_1, sm2_1, sm3_1, sm4_1, sm5_1, sm6_1, sm7_1, sm8_1, Code2, numb2, sm1_2, sm2_2, sm3_2, sm4_2, sm5_2, sm6_2, sm7_2, sm8_2
с "null" соответственно там где нет в какой-то таблице.
...
Рейтинг: 0 / 0
Помогите написать JOIN
    #39277202
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
akrush,

FULL JOIN + COALESCE тебе помогут. Правда в 2.5 FULL JOIN будет работать очень долго. Поэтому выворачиваться придётся через LEFT JOIN + UNION ALL + NOT EXISTS

ЗЫ. Если Code, numb действительно ключевые поля то запрос с суммированием и агрегатами бредовый
...
Рейтинг: 0 / 0
Помогите написать JOIN
    #39277208
akrush
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Симонов Денис,
Спасибо. Но я еще не умею писать JOIN, а время - это не критично. Если справится за 10-15 минут (у меня от 100-250 тыс. строк в 6 отчетов) по каждому отчету - это будет супер

Можете помочь как правильно написать. То что я писал ушло в глубокий сон (выборку) я так и не дождался ответа в IBExper и снял его
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
select
    pnew.code as new_code,     pnew.numb as new_numb,
    sum(pnew.sm1) as sm1_new,  sum(pnew.sm2) as sm2_new,
    sum(pnew.sm3) as sm3_new,  sum(pnew.sm4) as sm4_new,
    sum(pnew.sm5) as sm5_new,  sum(pnew.sm6) as sm6_new,
    sum(pnew.sm7) as sm7_new,  sum(pnew.sm8) as sm8_new,

    pold.code as old_code,     pold.numb as old_numb,
    sum(pold.sm1) as sm1_old,  sum(pold.sm2) as sm2_old,
    sum(pold.sm3) as sm3_old,  sum(pold.sm4) as sm4_old,
    sum(pold.sm5) as sm5_old,  sum(pold.sm6) as sm6_old,
    sum(pold.sm7) as sm7_old,  sum(pold.sm8) as sm8_old
from
    "1306_NEW" pnew full join "1306_OLD" pold on pnew.code=pold.code and pnew.numb=pold.numb
group by
    pnew.code,
    pnew.numb,
    pold.code,
    pold.numb
...
Рейтинг: 0 / 0
Помогите написать JOIN
    #39277215
Arioch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
akrush,

...а индекс у тебя есть?

сделай в IBE своему запросу Prepare - какой план запроса покажет?
...
Рейтинг: 0 / 0
Помогите написать JOIN
    #39277217
Arioch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Симонов Денис,

а нельзя сначала сделать отбор distinct пар code, numb с обеих таблиц, а потом просуммировать for-select'ом
...
Рейтинг: 0 / 0
Помогите написать JOIN
    #39277230
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Arioch,

2.5 не умеет использовать индексы для FULL JOIN

akrush,

Код: sql
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.
select
    pnew.code as code,     pnew.numb as numb,
    sum(pnew.sm1) as sm1_new,  sum(pnew.sm2) as sm2_new,
    sum(pnew.sm3) as sm3_new,  sum(pnew.sm4) as sm4_new,
    sum(pnew.sm5) as sm5_new,  sum(pnew.sm6) as sm6_new,
    sum(pnew.sm7) as sm7_new,  sum(pnew.sm8) as sm8_new,

    sum(pold.sm1) as sm1_old,  sum(pold.sm2) as sm2_old,
    sum(pold.sm3) as sm3_old,  sum(pold.sm4) as sm4_old,
    sum(pold.sm5) as sm5_old,  sum(pold.sm6) as sm6_old,
    sum(pold.sm7) as sm7_old,  sum(pold.sm8) as sm8_old
from
    "1306_NEW" pnew left join "1306_OLD" pold on pnew.code=pold.code and pnew.numb=pold.numb
group by
    pnew.code,
    pnew.numb
union all
select
    pold.code as code,     pold.numb as numb,
    null as sm1_new,  null as sm2_new,
    null as sm3_new,  null as sm4_new,
    null as sm5_new,  null as sm6_new,
    null as sm7_new,  null as sm8_new,

    sum(pold.sm1) as sm1_old,  sum(pold.sm2) as sm2_old,
    sum(pold.sm3) as sm3_old,  sum(pold.sm4) as sm4_old,
    sum(pold.sm5) as sm5_old,  sum(pold.sm6) as sm6_old,
    sum(pold.sm7) as sm7_old,  sum(pold.sm8) as sm8_old
from
    "1306_OLD" pold
where not exists(select * from "1306_NEW" pnew where pnew.code=pold.code and pnew.numb=pold.numb)
group by
    pold.code,
    pold.numb
...
Рейтинг: 0 / 0
Помогите написать JOIN
    #39277317
akrush
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Симонов Денис,

Спасибо. Получилось. Сейчас проверю все ли дела попали :)
...
Рейтинг: 0 / 0
Помогите написать JOIN
    #39277384
akrush
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Симонов Денис,

Подскажите: а как результат выполнения запроса в IBExperte Сразу перегнать/сохранить в таблицу в текущей БД
...
Рейтинг: 0 / 0
Помогите написать JOIN
    #39277388
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
akrush,

в какую таблицу? Читать совсем не хотим? Для этого есть куча способов INSERT ... SELECT, MERGE, можно EXECUTE BLOCK написать, ну или хранимую процедуру, если будет использоваться не однократно.

С FULL JOIN я помог, потому что далеко не все знают на что его заменить чтобы в FB < 3.0 работало быстро. А вот рассказывать элементарные вещи про вставку записей в другую таблицу не хочу. Это всё описано в документации.
...
Рейтинг: 0 / 0
Помогите написать JOIN
    #39277397
akrush
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Симонов Денис,

Спасибо за подсказку. Совсем забыл
...
Рейтинг: 0 / 0
Помогите написать JOIN
    #39277399
akrush
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Симонов Денис,

ЕЩЕ РАЗ ВСЕМ О-Г-Р-О-М-Н-О-Е СПАСИБО.
Получилось очень красиво и быстро.
Код: sql
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.
CREATE TABLE CALC_1307 (
    CODE INTEGER,
    NUMB BIGINT,
    SM1_NEW DOUBLE PRECISION,
    SM2_NEW DOUBLE PRECISION,
    SM3_NEW DOUBLE PRECISION,
    SM4_NEW DOUBLE PRECISION,
    SM5_NEW DOUBLE PRECISION,
    SM6_NEW DOUBLE PRECISION,
    SM7_NEW DOUBLE PRECISION,
    SM8_NEW DOUBLE PRECISION,
    SM1_OLD DOUBLE PRECISION,
    SM2_OLD DOUBLE PRECISION,
    SM3_OLD DOUBLE PRECISION,
    SM4_OLD DOUBLE PRECISION,
    SM5_OLD DOUBLE PRECISION,
    SM6_OLD DOUBLE PRECISION,
    SM7_OLD DOUBLE PRECISION,
    SM8_OLD DOUBLE PRECISION);
COMMIT;

INSERT INTO CALC_1307 (CODE, NUMB, SM1_NEW, SM2_NEW, SM3_NEW, SM4_NEW, SM5_NEW, SM6_NEW, SM7_NEW, SM8_NEW, SM1_OLD, SM2_OLD, SM3_OLD, SM4_OLD, SM5_OLD, SM6_OLD, SM7_OLD, SM8_OLD)
    select
    pnew.code as code,
    pnew.numb as numb,
    sum(pnew.sm1) as sm1_new,    sum(pnew.sm2) as sm2_new,
    sum(pnew.sm3) as sm3_new,    sum(pnew.sm4) as sm4_new,
    sum(pnew.sm5) as sm5_new,    sum(pnew.sm6) as sm6_new,
    sum(pnew.sm7) as sm7_new,    sum(pnew.sm8) as sm8_new,
                             
    sum(pold.sm1) as sm1_old,    sum(pold.sm2) as sm2_old,
    sum(pold.sm3) as sm3_old,    sum(pold.sm4) as sm4_old,
    sum(pold.sm5) as sm5_old,    sum(pold.sm6) as sm6_old,
    sum(pold.sm7) as sm7_old,    sum(pold.sm8) as sm8_old
from
    "1307_NEW" pnew left join "1307_OLD" pold on pnew.code=pold.code and pnew.numb=pold.numb
group by
    pnew.code,
    pnew.numb
union all
select
    pold.code as code,     pold.numb as numb,
    0 as sm1_new,  0 as sm2_new,
    0 as sm3_new,  0 as sm4_new,
    0 as sm5_new,  0 as sm6_new,
    0 as sm7_new,  0 as sm8_new,

    sum(pold.sm1) as sm1_old,  sum(pold.sm2) as sm2_old,
    sum(pold.sm3) as sm3_old,  sum(pold.sm4) as sm4_old,
    sum(pold.sm5) as sm5_old,  sum(pold.sm6) as sm6_old,
    sum(pold.sm7) as sm7_old,  sum(pold.sm8) as sm8_old
from
    "1307_OLD" pold
where not exists(select * from "1307_NEW" pnew where pnew.code=pold.code and pnew.numb=pold.numb)
group by
    pold.code,
    pold.numb;
COMMIT;

CREATE TABLE CALC_1307_END (
    CODE INTEGER,
    NUMB BIGINT,
    SM1 DOUBLE PRECISION,
    SM2 DOUBLE PRECISION,
    SM3 DOUBLE PRECISION,
    SM4 DOUBLE PRECISION,
    SM5 DOUBLE PRECISION,
    SM6 DOUBLE PRECISION,
    SM7 DOUBLE PRECISION,
    SM8 DOUBLE PRECISION);
COMMIT;

INSERT INTO CALC_1307_END (CODE, NUMB, SM1, SM2, SM3, SM4, SM5, SM6, SM7, SM8)
    select
  c.code,
  c.numb,
  c.sm1_new-c.sm1_old as sm1,
  c.sm2_new-c.sm2_old as sm2,
  c.sm3_new-c.sm3_old as sm3,
  c.sm4_new-c.sm4_old as sm4,
  c.sm5_new-c.sm5_old as sm5,
  c.sm6_new-c.sm6_old as sm6,
  c.sm7_new-c.sm7_old as sm7,
  c.sm8_new-c.sm8_old as sm8
From
  calc_1307 c;

COMMIT;



Скорость просто СУПЕР. З=Количество записей в исходных таблицах и в результате:
1307_NEW
1307_OLD CALC_1307
CALC_1307_END
...
Рейтинг: 0 / 0
Помогите написать JOIN
    #39277400
akrush
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
akrush,
Случайно нажал опубликовать

Кол-во записей:
1307_NEW - 66558
1307_OLD - 56874
CALC_1307 - 29066
CALC_1307_END - 26099

Время выполнения: 3s 485ms
...
Рейтинг: 0 / 0
13 сообщений из 13, страница 1 из 1
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Помогите написать JOIN
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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