SUM () Несколько датериодов в одном наборе данных - PullRequest
0 голосов
/ 24 сентября 2018

Мне нужны некоторые идеи о том, как решить проблему, возникшую у меня с запросом отчета.
Используются 3 столбца, все в одной таблице: «EventDate», «Distance» и «EventName».Для каждого зарегистрированного события время и дата события записываются вместе с «EventName».
Мне нужен запрос, чтобы вычислить SUM (расстояние) между так называемыми основными событиями, основные события имеют заданные именано может повторяться несколько раз в день.

Я не могу придумать, как написать запрос, использующий «EventDate», где «EventName» = «что-то», и продолжая до тех пор, пока вы не достигнете «EventName» = «Что-то еще», затем задайте SUM (Расстояние), затемначните заново со следующего «EventName» = «что-то» и продолжайте делать это до тех пор, пока в наборе данных не останется больше записей с «EventName» = «что-то».

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

    EventName              EventDate                Distance
    All Clear              2018-09-06 01:54:00.000  0
    Passing 3 Nmz          2018-09-06 02:35:00.000  0
    Commence Sea Passage   2018-09-06 03:00:00.000  10
    Commence Sea Passage   2018-09-06 03:00:00.000  0
    DailyReport            2018-09-06 12:00:00.000  119
    End Of Sea Passage     2018-09-07 05:45:00.000  335
    Pilot Embarked         2018-09-07 06:00:00.000  0
    Tug Fast               2018-09-07 07:40:00.000  0
    Mooring Commenced      2018-09-07 08:15:00.000  0
    All Fast               2018-09-07 08:45:00.000  19
    Pilot Embarked         2018-09-07 23:18:00.000  0
    Unmooring Commenced    2018-09-07 23:45:00.000  0
    All Clear              2018-09-08 00:00:00.000  0,01
    Pilot Disembarked      2018-09-08 01:30:00.000  0
    Commence Sea Passage   2018-09-08 01:40:00.000  17
    Voyage Complete        2018-09-08 01:40:00.000  0
    Voyage Commenced       2018-09-08 01:45:00.000  0
    End Of Sea Passage     2018-09-08 10:00:00.000  83
    Anchored               2018-09-08 11:00:00.000  3,2
    DailyReport            2018-09-08 12:00:00.000  0
    All Fast               2018-09-09 20:00:00.000  40

В приведенном выше наборе данных я хотел бы указать расстояние от «All Clear», включая «All Fast».

Ответы [ 2 ]

0 голосов
/ 24 сентября 2018

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

/*Input Table: EventLog (EventName nvarchar(max), EventDate datetime, Distance decimal(18,2))*/
DECLARE @BeginDate AS datetime
DECLARE @EndDate AS datetime
DECLARE @RowNo AS integer
--result table
DECLARE @MainEventTable table
    (RowNumber integer,
    MainEventName nvarchar(256),
    MainEventDate datetime,
    SumDistance decimal(18,2))

--Create List of Main Events
INSERT INTO @MainEventTable (RowNumber, MainEventName, MainEventDate)
    SELECT ROW_NUMBER() OVER(ORDER BY EventDate ASC), EventName, EventDate
    FROM EventLog --!! put here name of your table
    WHERE EventName IN ('Main1','Main2','Main3') --!! put here names of main events

--check number of main events
SET @RowNo = (SELECT ISNULL(MAX(RowNumber),0) FROM @MainEventTable)
SET @BeginDate = CONVERT(datetime, '9999.12.12', 102)

WHILE @RowNo > 0
    BEGIN
        SET @EndDate = @BeginDate
        SET @BeginDate = (SELECT MainEventDate FROM @MainEventTable WHERE RowNumber = @RowNo)

        UPDATE @MainEventTable 
        SET SumDistance = (
            SELECT
                SUM(Distance)
            FROM EventLog --!! put here name of your table
            WHERE EventDate >= @BeginDate AND EventDate < @EndDate)
        WHERE RowNumber = @RowNo

        SET @RowNo = @RowNo - 1
    END

SELECT * FROM @MainEventTable ORDER BY RowNumber

Вход (EventLog):

EventName   EventDate               Distance
NotMain     1905-07-04 00:00:00.000 2
Main3       1905-07-05 00:00:00.000 2
Main2       1905-07-06 00:00:00.000 2
NotMain     1905-07-07 00:00:00.000 3
NotMain     1905-07-08 00:00:00.000 2
Main1       1905-07-09 00:00:00.000 1

Выход:

RowNumber   MainEventName   MainEventDate           SumDistance
1           Main3           1905-07-05 00:00:00.000 2
2           Main2           1905-07-06 00:00:00.000 7
3           Main1           1905-07-09 00:00:00.000 1
0 голосов
/ 24 сентября 2018

Это звучит как проблема пропусков и островков.

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

Пример фрагмента:

-- Using a table variable for testing purposes
declare @Table table (EventDate datetime, EventName varchar(30), Distance decimal(9,2));

-- Sample data
insert into @Table (EventName, EventDate, Distance) values
 ('All Clear','2018-09-06 01:54',0)
,('Passing 3 Nmz','2018-09-06 02:35',0)
,('Commence Sea Passage','2018-09-06 03:00',10)
,('Commence Sea Passage','2018-09-06 03:00',0)
,('DailyReport','2018-09-06 12:00',119)
,('End Of Sea Passage','2018-09-07 05:45',335)
,('Pilot Embarked','2018-09-07 06:00',0)
,('Tug Fast','2018-09-07 07:40',0)
,('Mooring Commenced','2018-09-07 08:15',0)
,('All Fast','2018-09-07 08:45',19)
,('Pilot Embarked','2018-09-07 23:18',0)
,('Unmooring Commenced','2018-09-07 23:45',0)
,('All Clear','2018-09-08 00:00',0.01)
,('Pilot Disembarked','2018-09-08 01:30',0)
,('Commence Sea Passage','2018-09-08 01:40',17)
,('Voyage Complete','2018-09-08 01:40',0)
,('Voyage Commenced','2018-09-08 01:45',0)
,('End Of Sea Passage','2018-09-08 10:00',83)
,('Anchored','2018-09-08 11:00',3.2)
,('DailyReport','2018-09-08 12:00',0)
,('All Fast','2018-09-09 20:00',40)
;

-- Query
;with CTE as
(
  select EventDate, Distance, EventName
   , iif(EventName = 'All Clear',1,0) as isMainEvent
  from @Table
)
select 
 min(EventDate) as MinDateTime,
 max(EventDate) as MaxDateTime,
 sum(Distance) as TotalDistance
from
(
    select *
    , row_number() over (order by EventDate) - row_number() over (partition by isMainEvent order by EventDate) as rnk
    from CTE
) q
where isMainEvent = 0
group by rnk
order by rnk;

Выход:

MinDateTime         MaxDateTime         TotalDistance
------------------- ------------------- -------------
2018-09-06 02:35:00 2018-09-07 23:45:00        483.00
2018-09-08 01:30:00 2018-09-09 20:00:00        143.20
...