MS Access 2016 - Сравните даты в одной таблице - PullRequest
0 голосов
/ 23 октября 2019

У меня есть две таблицы, пользователи и задания. Идентификатор пользователя и идентификатор задания являются как автономными, так и первичными ключами для своих таблиц.

Таблица пользователей:

UID | Uname | Uphone | etc...
1   | Billy | 911    |
2   | Alan  | 119    | 
3   | Maria | 191    |

Таблица заданий:

JID | UID   | Jtitle  | Date   | etc...
1   | 1     | PenTest | 12Aug
2   | 1     | Consult | 15Nov
3   | 2     | VulScan | 05Sep
4   | 2     | PenTest | 15Sep
5   | 1     | PenTest | 30Dec
6   | 2     | PenTest | 13Oct
7   | 3     | VulScan | 10Nov

Что мне нужно сделать, это взять задания для каждого UID и измерить количество дней междудве даты, самая последняя и следующая в будущем. Например, сегодня 23 октября, поэтому мне нужно знать количество дней между 12 августа и 15 ноября для Билли (UID 1). Кроме того, если работа не запланирована на будущее, то в идеале я бы хотел, чтобы ячейка «будущее» была пустой для Алана (UID 2).

В моей голове это выглядело бы примерно так, как показано в таблице ниже. .

UID  | Past  | Future | Difference  |
1    | 12Aug | 15Nov  |  95
2    | 13Oct |        |  
3    |       | 10Nov  |  

Почти все пользователи будут иметь хотя бы одну работу в прошлом, но не гарантируют работу в будущем. Возможно, что пользователь будет создан, а дата его работы еще не наступила, как в случае с Марией (UID 3), но это будет ограниченный сценарий (скорее всего, от найма до работы у пользователя будет меньше тридцати дней).

Я пытался выяснить это пару дней назад и ничего не получил. Возможно, мой код был неправильным, но я не смог получить два оставшихся соединения, чтобы решить, и тогда возникает проблема расчета разницы.

1 Ответ

0 голосов
/ 23 октября 2019

Вот одно решение (для sqlserver, msaccess sql еще ниже) - что должно произойти, когда дата равна сегодняшнему дню?

-- for testing, declare table and insert some date into it
declare @Jobs table (JID int, UID int, Jtitle varchar(50), aDate datetime);
insert into @Jobs values (1, 1, 'PenTest', '12Aug2019');
insert into @Jobs values (2, 1, 'Consult', '15Nov2019');
insert into @Jobs values (3, 2, 'VulScan', '05Sep2019');
insert into @Jobs values (4, 2, 'PenTest', '15Sep2019');
insert into @Jobs values (5, 1, 'PenTest', '30Dec2019');
insert into @Jobs values (6, 2, 'PenTest', '13Oct2019');
insert into @Jobs values (7, 3, 'VulScan', '10Nov2019');

-- FULL Join the max(Past) and the min(Future) and convert the dates.
Select 
     COALESCE(a.UID, b.UID) as UID, 
     Left(Convert(varchar, Past, 106), 6) as Past,
     LEFT(Convert(varchar, Future, 106), 6) as Future,
     DATEDIFF(day, Past, Future) as Difference  
FROM
    (Select UID, Max(aDate) as Past from @Jobs where aDate <= GETDATE() Group By UID)a
FULL JOIN
    (Select UID, Min(aDate) as Future from @Jobs where aDate > GETDATE() Group By UID) b
ON a.UID = B.UID

Результаты: -

UID Past    Future  Difference
1   12 Aug  15 Nov  95
2   13 Oct  NULL    NULL
3   NULL    10 Nov  NULL

SQLдля MSACCESS использует объединение левого и правого объединений для получения одинаковых результатов -

Select 
     NZ(a.UID, b.UID) as UID, 
     format( aPast, "ddMMM") as Past,
     format( aFuture, "ddMMM") as Future,
     DATEDIFF("d", aPast, aFuture) as Difference  
FROM
    (Select UID, Max(aDate) as aPast from Jobs where aDate <= DATE() Group By UID)a
LEFT JOIN
    (Select UID, Min(aDate) as aFuture from Jobs where aDate > DATE() Group By UID) b
ON a.UID = B.UID

UNION

Select 
     NZ(a.UID, b.UID) as UID, 
     format( aPast, "ddMMM") as Past,
     format( aFuture, "ddMMM") as Future,
     DATEDIFF("d", aPast, aFuture) as Difference  
FROM
    (Select UID, Max(aDate) as aPast from Jobs where aDate <= DATE() Group By UID)a
RIGHT JOIN
    (Select UID, Min(aDate) as aFuture from Jobs where aDate > DATE() Group By UID) b
ON a.UID = B.UID

Чтобы получить также Uname, просто оберните вышеприведенное как подвыбор и объедините его с пользователем. Мне пришлось конвертировать в Integer (Cint) UID, чтобы он работал.

SELECT  u.Uname, z.*  

FROM (
Select 
     NZ(a.UID, b.UID) as UID, 
     format( aPast, "ddMMM") as Past,
     format( aFuture, "ddMMM") as Future,
     DATEDIFF("d", aPast, aFuture) as Difference  
FROM
    (Select UID, Max(aDate) as aPast from Jobs where aDate <= DATE() Group By UID)a
LEFT JOIN
    (Select UID, Min(aDate) as aFuture from Jobs where aDate > DATE() Group By UID) b
ON a.UID = B.UID

UNION

Select 
     NZ(a.UID, b.UID) as UID, 
     format( aPast, "ddMMM") as Past,
     format( aFuture, "ddMMM") as Future,
     DATEDIFF("d", aPast, aFuture) as Difference  
FROM
    (Select UID, Max(aDate) as aPast from Jobs where aDate <= DATE() Group By UID)a
RIGHT JOIN
    (Select UID, Min(aDate) as aFuture from Jobs where aDate > DATE() Group By UID) b
ON a.UID = B.UID
)  as z
Left Join [User] as u
On cint(z.UID) = cint(u.UID)

Я живу между Оклендом и Беркли, и у нас есть много местных пивных баров.

...