Группировать по запросу с перекрытием дат - PullRequest
0 голосов
/ 11 июня 2019

У меня есть некоторые данные с потенциально перекрывающимися датами, которые мне нужно сгруппировать.Прежде всего позвольте мне объяснить таблицы:

tblBusinessDays - В этой таблице все рабочие дни пронумерованы.Не спрашивай меня почему, я унаследовал это.Обратите внимание, что числа дней повторяются для пятницы, субботы и воскресенья.Они делают то же самое в праздничные дни.

DayNumber   Date        Day
3           12/3/2003   Wednesday
4           12/4/2003   Thursday
5           12/5/2003   Friday
5           12/6/2003   Saturday
5           12/7/2003   Sunday
6           12/8/2003   Monday
7           12/9/2003   Tuesday

tblPends - в этой таблице перечислены все ожидающие события (раз транзакция была приостановлена).

ClientID    AcctNbr  TransID    InventoryID PendID  PendOpenDT  PendCloseDT 
0           0605161  8378488    1           97455   1/25/2012   2/9/2012    
0           0605161  8378488    1           98051   2/6/2012    2/17/2012

Запрос, который у меня есть на данный момент, учитывает записи, в которых PendOpenDt и PendCloseDt идентичны для обеих записей или даты открытия и закрытия не перекрываются.Это простой запрос Group By, который собирает 95% данных.Однако я понятия не имею, как учитывать записи, подобные приведенным выше, где PendOpenDt второй записи перекрывает PendCloseDt предыдущей записи.

Вот что у меня есть:

SELECT 
    tblPends.ClientID, 
    tblPends.AcctNbr, 
    tblPends.TransID,
    tblPends.InventoryID, 
    tblBusinessDays.DayNumber AS OpenDayNumber, 
    tblBusinessDays_1.DayNumber AS CloseDayNumber, 
    [tblBusinessDays_1].[DayNumber]-[tblBusinessDays].[DayNumber] AS TotalPendDays, 
    Sum(1) AS [Key]
FROM (tblPends 
    LEFT JOIN tblBusinessDays 
        ON tblPends.PendOpenDT = tblBusinessDays.Date) 
    LEFT JOIN tblBusinessDays AS tblBusinessDays_1 
        ON tblPends.PendCloseDT = tblBusinessDays_1.Date
GROUP BY 
    tblPends.ClientID, 
    tblPends.AcctNbr, 
    tblPends.TransID,
    tblPends.InventoryID, 
    tblBusinessDays.DayNumber, 
    tblBusinessDays_1.DayNumber, 
    [tblBusinessDays_1].[DayNumber]-[tblBusinessDays].[DayNumber]
HAVING (((
    tblPends.ClientID)=[Forms]![frmInventory]![ClientId]) 
    AND ((tblPends.AcctNbr)=[Forms]![frmInventory]![AcctNbr]) 
    AND ((tblPends.TransID)=[Forms]![frmInventory]![TransID])
    AND ((tblPends.InventoryID)=[Forms]![frmInventory]![InventoryID]));

Полученные данные возвращаются так:

ClientID    AcctNbr TransID  InventoryID   OpenDayNumber  CloseDayNumber   TotalPendDays    Key
0           0605161 8378488  1             2065           2076             11               1
0           0605161 8378488  1             2073           2082              9               1

В результате TotalPendDays добавляет к 20, тогда как к 17 следует добавить. В приведенном выше случае желаемым результатом может быть одна запись, возвращенная сTotalPendDays равен 17.

т.е.

ClientID    AcctNbr TransID  InventoryID   TotalPendDays    Key
0           0605161 8378488  1             17               1

Пока у меня есть AcctNbr, ClientID и TransID, я могу ссылаться и получать оставшиеся данные.

Если у меня что-то вроде этого:

ClientID    AcctNbr TransID  InventoryID   OpenDayNumber  CloseDayNumber   TotalPendDays    Key
0           0605161 8378488  1             2065           2076             11               1
0           0605161 8378488  1             2079           2082              3               1

Тогда мне нужно это вернуть:

ClientID    AcctNbr TransID  InventoryID   TotalPendDays    Key
0           0605161 8378488  1             14               1

Если у меня что-то вроде этого:

ClientID    AcctNbr TransID  InventoryID   OpenDayNumber  CloseDayNumber   TotalPendDays    Key
0           0605161 8378488  1             2065           2076             11               1
0           0605161 8378488  1             2069           2074              5               1

ТогдаМне нужно, чтобы это возвращалось:

ClientID    AcctNbr TransID  InventoryID   TotalPendDays    Key
0           0605161 8378488  1             11               1

В этом последнем случае вся вторая запись полностью перекрывает первую, поэтому ее вообще не нужно считать.

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

1 Ответ

0 голосов
/ 11 июня 2019

Извините, это действительно сложная проблема, поэтому я не буду полностью на нее отвечать. Ответ может быть существенно более простым, если число ожидающих ограничено и не может быть бесконечным, или если вы просто используете решение VBA.

Давайте начнем с ограничения проблемы (извините, вам придется внести некоторые коррективы, чтобы использовать ее): я предоставлю код, который для определенного TransID, укажите количество дней.

Я также сделаю это в два этапа:

Query1:

SELECT base.AcctNbr, base.TransID, tblBusinessDays.DayNumber
FROM (SELECT DISTINCT AcctNbr, TransID FROM tblPends) base
INNER JOIN tblPends sub ON base.AcctNbr = sub.AcctNbr
    AND base.TransID  = sub.TransID)
INNER JOIN tblBusinessDays ON (tblBusinessDays.[Date] <= sub.PendOpenDT  AND tblBusinessDays.[Date] >= sub.PendCloseDT

Этот запрос вернет все возможные номера рабочего дня для данного AcctNbr и TransID (я предполагаю, что это отдельные записи, которые связывают эти ожидания друг с другом).

Тогда все, что нам нужно сделать, это COUNT(Distinct). К сожалению, Access не поддерживает это, поэтому мы должны сделать это в два этапа:

Query2:

SELECT AcctNbr, TransID,  Count(DayNumber)
FROM (SELECT DISTINCT * FROM Query1) q
GROUP BY AcctNbr, TransID

Query2 будет содержать то, что вы ищете, различное количество идентификаторов даты в пределах даты открытия и закрытия.

...