Вот базовое воссоздание вашего стола.Используйте его в качестве примера для своей дальнейшей работы или для дальнейшего объяснения того, что задача, которую вы выполнили.
Возьмите ее в качестве отправной точки.
AFAIR Firebird возвращает арифметические операции, такие как (DATE - DATE) в днях, такие же, как PostgreSQL , но вы должны проверить это. MySQL например, кажется, считает дату в разных единицах. SQL Fiddle не поддерживает Firebird .
Вы просто не можете правильно преобразовать количество дней в годы / месяцы / дни, потому что есть разныегоды (365 или 366 дней) и разные месяцы (от 28 до 31 дня), так что вам решать, что вы будете считать «более или менее в год» и «более или менее в месяц» здесь и делать математику,Вы можете заключить математику в какую-нибудь хранимую процедуру, например, , чтобы повторно использовать ее в различных запросах LEFT JOIN
.
Этот запрос использует JOIN
, поэтому он предполагаетчто записи данных для каждой пары человек-контакт присутствуют как в таблица1 , так и таблица2 , а затем только в одной строке в каждой таблице.Если у вас есть пары человек-контакт, у которых нет строки в какой-либо таблице или их несколько - возможно, вы захотите соответствующим образом изменить запрос.
В частности, вы можете создать помощникатаблица, постоянная или GLOBAL TEMPORARY TABLE
, которая будет накапливать записи как из table1 , так и table2 , просто для их суммирования.Это может решить проблему наличия строк в одной из таблиц, но не в другой.Это может или не может решить проблему наличия нескольких строк в одной таблице для одного и того же контакта.
Также был вопрос, что автор темы не отвечает, поэтому он остается нерешенным:
В ваших данных есть одна проблема: дата 2000-03-16 одновременно относится к ОБА контрактам, что, по-видимому, является внутренним противоречием.Как конкретно тогда вы будете считать дни?
Здесь ниже он учитывается дважды, если только сегмент не является полуоткрытым, а DATE_TO
должен фактически означать DATE_AFTER
.
SQL Fiddle
Настройка схемы PostgreSQL 9.6 :
create table TABLE1
(ID integer, ID_CONTACT integer, DATE_FROM date , DATE_TO date);
create table TABLE2
(ID integer, ID_CONTACT integer, DATE_FROM date , DATE_TO date);
INSERT INTO TABLE1 (ID, ID_CONTACT, DATE_FROM, DATE_TO)
VALUES ('1', '52', '1988-09-15', '2000-03-16');
INSERT INTO TABLE2 (ID, ID_CONTACT, DATE_FROM, DATE_TO)
VALUES ('1', '52', '2000-03-16', '2005-02-28');
Запрос 1 :
select id, id_contact, date_to - date_from as D1 from table1
union all
select id, id_contact, date_to - date_from as D2 from table2
Результаты :
| id | id_contact | d1 |
|----|------------|------|
| 1 | 52 | 4200 |
| 1 | 52 | 1810 |
Запрос 2 :
with D1 as (
select id, id_contact, date_to - date_from as D1 from table1 ),
D2 as (
select id, id_contact, date_to - date_from as D2 from table2 )
Select d1.id, d2.id_contact, d1.d1 + d2.d2
From D1, D2
Where D1.id = D2.id
and D1.id_contact = D2.id_contact
Результаты :
| id | id_contact | ?column? |
|----|------------|----------|
| 1 | 52 | 6010 |
SQL Fiddle
Настройка схемы PostgreSQL 9.6 :
create table TABLE1
(ID integer, ID_CONTACT integer, DATE_FROM date , DATE_TO date);
create table TABLE2
(ID integer, ID_CONTACT integer, DATE_FROM date , DATE_TO date);
create table TABLE3
(ID integer, ID_CONTACT integer, DATE_FROM date , DATE_TO date);
INSERT INTO TABLE1 (ID, ID_CONTACT, DATE_FROM, DATE_TO)
VALUES ('1', '52', '1988-09-15', '2000-03-16');
INSERT INTO TABLE2 (ID, ID_CONTACT, DATE_FROM, DATE_TO)
VALUES ('1', '52', '2000-03-16', '2005-02-28');
INSERT INTO TABLE3 SELECT * FROM TABLE1;
INSERT INTO TABLE3 SELECT * FROM TABLE2;
Запрос 1 :
Select id, id_contact, SUM( DATE_TO - DATE_FROM )
From TABLE3
Group By 1, 2
Результаты :
| id | id_contact | sum |
|----|------------|------|
| 1 | 52 | 6010 |