我需要一些有关如何解决报表查询问题的想法。
正在使用3列,均在同一表中,分别为“ EventDate”,“ Distance”和“ EventName”。
对于已注册的每个事件,事件的时间和日期都会与“ EventName”一起记录。
我需要查询执行的操作是计算所谓的主要事件之间的SUM(Distance),主要事件具有设置的名称,但一天可能多次发生。
我想不出一种写使用“ EventDate”的查询的方法,其中“ EventName” =“某物”,然后继续进行直到到达“ EventName” =“某物”,然后给出SUM(Distance),然后重新开始从下一个“ EventName” =“ something”开始,直到数据集中不再有“ EventName” =“ something”的记录为止。
很抱歉,如果让您感到困惑,请多多帮助或帮助我解决此问题的代码段。
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”)保持距离。
答案 0 :(得分:1)
这听起来像是一个空白与孤岛的问题。
您可以根据事件类型生成排名。
然后对那个等级进行分组,并计算出与之的总距离。
示例代码段:
-- 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
答案 1 :(得分:0)
您可以尝试此解决方案。它创建仅包含主要事件的临时表,然后在循环中检查主要事件之间的距离的输入数据总和:
/*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
输入(事件日志):
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