我正在尝试找一个更好的方法来做一个Crystal Report(别人的)...在组中添加非重叠时间。 这显然是一个古老的问题...... 是否有获取技术
假设开始时间(和/或组,子组)和开始和结束的初始顺序是单独的字段。
一种图形示例:
Group 1
SubGroup A
Tkt 1 |--start&end---| "16"
Tkt 2 |----tart&end----| "18"
Tkt 3 |--art&end---| "14"
Tkt 4 |--S & E -| "11"
SubGroup B
Tkt 5 |-S&E-| "7"
Tkt 6 |-S&E-| "7"
Tkt 7 |-S&E-| "7"
...
(equiv adjusted start/end w/in sub-group):
Group 1
SubGroup A ( w/ "elapsed time" of "33" )
Tkt 1 |--start&end---| <- Regular "16"
Tkt 2 |-----| <- Adjusted "start" "6"
Tkt 3 | <- Adjusted "start" & "end" "0"
Tkt 4 |--S & E -| <- Regular "11"
SubGroup B ( w/ "elapsed time" of "17" )
Tkt 5 |-S&E-| <- Regular "7"
Tkt 6 |-S&E-| <- Regular (no overlap) "7"
Tkt 7 |-| <- Adjusted "Start" "3"
...
我不是在谈论在这一点上获得总和,只是说明根据之前的记录调整开始/结束。
在报告中,他们针对每个记录执行多个公式,针对在组中的第一个记录上设置的两个变量,然后根据当前记录设置/更新AdjustedStart,AdjustedEnd的值,并将AdjustedStart,AdjustedEnd传递给计算时差的另一个公式,稍后加总。目前的技术很慢,我不能做一个所需的漂亮的交叉表。
我在想/希望这已经在SQL中解决了,因为我们不能在数据库服务器上放置任何proc,临时表等。我试图找出一种方式w / CTE和(重新)诅咒,使用Group / SubGroup作为父母,CASE来比较当前值w / last-parent值。这是响铃还是听起来合理?
水晶的能力很多,但这似乎是一个不适合它的。
马克
答案 0 :(得分:0)
我正在做这件事......
SELECT
CUR.subgroup,
CUR.ticket,
COALESCE(MAX(PARENT.end_time), CUR.start_time) AS start_time,
CASE
WHEN CUR.end_time < MAX(PARENT.end_time) THEN MAX(PARENT.end_time)
ELSE CUR.end_time
END
FROM
My_Table CUR
LEFT OUTER JOIN My_Table PARENT ON
PARENT.start_time <= CUR.start_time AND
PARENT.end_time > CUR.start_time AND
PARENT.ticket <> CUR.ticket AND
PARENT.subgroup = CUR.subgroup
GROUP BY
CUR.subgroup,
CUR.ticket,
CUR.start_time,
CUR.end_time
答案 1 :(得分:0)
我很感谢你很久以前问过这个问题,但它对我感兴趣,所以我做了一些研究,找到了Jeff Moden的解决方案;他写了一篇关于分组日期孤岛的文章,您可以在这里找到:Group Islands of Contiguous Dates(需要登录但可以免费注册)。
我假设你在一个子组中每天都有一个包含行的表,所以“Tkt1”有16行,“Tkt2”有18行等。如果不是这样,你只有启动和每个“Tkt”的结束日期,您必须使用Calendar
表来推断每个范围的行。
杰夫的解决方案使用ROW_NUMBER
和DATEDIFF
技巧对日期岛进行分组。
WITH Grouped_Dates AS
( -- Find the unique dates and assign them to a group.
-- The group looks like a date but the date means nothing except that adjacent
-- dates will be a part of the same group.
SELECT group_name,
unique_date = tkt_date,
date_group = DATEADD(dd, -ROW_NUMBER() OVER (PARTITION BY group_name ORDER BY group_name, tkt_date), tkt_date)
FROM t
GROUP BY group_name, tkt_date
)
-- Now, if we find the MIN and MAX date for each date_group, we'll have the
-- Start and End dates of each group of contiguous daes. While we're at it,
-- we can also figure out how many days are in each range of days.
SELECT group_name,
start_date = MIN(unique_date),
end_date = MAX(unique_date),
days = DATEDIFF(dd,MIN(unique_date),MAX(unique_date))+1
FROM Grouped_Dates
GROUP BY group_name, date_group
ORDER BY group_name, start_date
该查询的结果是
group_name start_date end_date days ---------- ---------- ---------- ---- Group1 2012-01-01 2012-01-22 22 Group1 2012-01-24 2012-02-03 11 Group2 2012-01-09 2012-01-15 7 Group2 2012-01-18 2012-01-27 10
我根据您的问题创建了一个包含示例数据的SQL Fiddle。
然后,您可以对每个组进行求和,以计算花费的总时间。