SQL 从另一个值为 MIN 值的列中获取一个值
SQL Getting a value from a column where another value is MIN value
我在 SQL 方面经验不足,我正在尝试从另一个值是最小值的行中获取一个值。
我尝试了几件事,但在这个论坛上找不到答案。
我的SQL:
select
Name,
MIN(StartDateAndTime) as StartTime,
MAX(EndDateAndTime) as EndTime
from tblWorkingTimes
group by Name,
convert(date, StartDateAndTime)
所以我有一个 table,其中包含一个 driver 白天完成的所有操作(驾驶、休息、加载...),我想每天做一个总结。
每个动作还提供一个 StartPositionText 和 EndPositionText。 (例如“ThisStreet 666, 9999 City”)
以上 SQL 有效,但我想添加 StartPositionText 和 EndPositionText。
所以我需要从 w.StartDateAndTime = MIN(w.StartDateAndTime) 的行获取 StartPositionText
和行中的 EndPositionText,其中 w.EndDateAndTime = Max(w.EndDateAndTime)。
我尝试了 SELECT 但我不能在 WHERE 子句中使用 MIN(w.StartDateAndTime) 并且我无法让它与 HAVING 子句一起使用。
编辑:示例数据 tblWorkingTimes
Name
StartDateAndTime
EndDateAndTime
StartText
EndText
Jim
2021-09-09 07:28:16
2021-09-09 08:28:16
"StartPlace1"
"EndPlace1"
Jim
2021-09-09 08:28:16
2021-09-09 09:28:16
"StartPlace2"
"EndPlace2"
Jim
2021-09-09 09:28:16
2021-09-09 10:28:16
"StartPlace3"
"EndPlace3"
Jim
2021-09-09 10:28:16
2021-09-09 11:28:16
"StartPlace4"
"EndPlace4"
期望的输出
Name
StartDateAndTime
EndDateAndTime
StartText
EndText
Jim
2021-09-09 07:28:16
2021-09-09 11:28:16
"StartPlace1"
"EndPlace4"
提前致谢
您可以为此使用 FIRST_VALUE
和 LAST_VALUE
select
w.DriverName,
convert(date, w.StartDateAndTime) as DayPerformed,
MIN(w.StartDateAndTime) as StartTime,
MAX(w.EndDateAndTime) as EndTime
StartPositionText,
EndPositionText
from (
SELECT *,
StartPositionText = FIRST_VALUE(StartPositionText) OVER (PARTITION BY w.DriverName, convert(date, w.StartDateAndTime)
ORDER BY w.StartDateAndTime ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING),
EndPositionText = LAST_VALUE(EndPositionText) OVER (PARTITION BY w.DriverName, convert(date, w.StartDateAndTime)
ORDER BY w.StartDateAndTime ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING)
FROM webfleet.tblWorkingTimes w
) w
group by w.DriverName,
convert(date, w.StartDateAndTime),
StartPositionText,
EndPositionText;
与 Charlieface 类似的 FISRT_VALUE
和 LAST_VALUE
解决方案,但更直接一些。将 CAST
的开始日期和结束日期作为日期添加到分区 by,使用多个日期清理。
DECLARE @t1 TABLE (Driver VARCHAR(50), StartDateTime DATETIME, EndDateTime DATETIME, StartPlace VARCHAR(20), EndPlace VARCHAR(20))
INSERT INTO @t1
VALUES
('Jim','2021-09-09 07:28:16','2021-09-09 08:28:16',' "StartPlace1"',' "EndPlace1"'),
('Jim','2021-09-09 08:28:16','2021-09-09 09:28:16',' "StartPlace2"',' "EndPlace2"'),
('Jim','2021-09-09 09:28:16','2021-09-09 10:28:16',' "StartPlace3"',' "EndPlace3"'),
('Jim','2021-09-09 10:28:16','2021-09-09 11:28:16',' "StartPlace4"',' "EndPlace4"'),
('Jim','2021-09-10 06:28:16','2021-09-10 08:28:16',' "StartPlace1"',' "EndPlace1"'),
('Jim','2021-09-10 08:28:16','2021-09-10 09:28:16',' "StartPlace2"',' "EndPlace2"'),
('Jim','2021-09-10 09:28:16','2021-09-10 10:28:16',' "StartPlace3"',' "EndPlace3"'),
('Jim','2021-09-10 10:28:16','2021-09-10 11:30:16',' "StartPlace4"',' "EndPlace4"')
SELECT DISTINCT
Driver,
CAST(StartDateTime AS DATE) AS 'Date',
FIRST_VALUE(StartDateTime) OVER (PARTITION BY Driver, CAST(StartDateTime AS DATE) ORDER BY StartDateTime ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS StartDateTime,
LAST_VALUE(EndDateTime) OVER (PARTITION BY Driver, CAST(EndDateTime AS DATE) ORDER BY EndDateTime ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS EndDateTime,
FIRST_VALUE(StartPlace) OVER (PARTITION BY Driver, CAST(StartDateTime AS DATE) ORDER BY StartDateTime ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS StartDateTime,
LAST_VALUE(EndPlace) OVER (PARTITION BY Driver, CAST(EndDateTime AS DATE) ORDER BY EndDateTime ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS EndDateTime
FROM @t1
Driver
Date
StartDateTime
EndDateTime
StartDateTime
EndDateTime
Jim
2021-09-09
2021-09-09 07:28:16.000
2021-09-09 11:28:16.000
"StartPlace1"
"EndPlace4"
Jim
2021-09-10
2021-09-10 06:28:16.000
2021-09-10 11:30:16.000
"StartPlace1"
"EndPlace4"
我在 SQL 方面经验不足,我正在尝试从另一个值是最小值的行中获取一个值。 我尝试了几件事,但在这个论坛上找不到答案。
我的SQL:
select
Name,
MIN(StartDateAndTime) as StartTime,
MAX(EndDateAndTime) as EndTime
from tblWorkingTimes
group by Name,
convert(date, StartDateAndTime)
所以我有一个 table,其中包含一个 driver 白天完成的所有操作(驾驶、休息、加载...),我想每天做一个总结。 每个动作还提供一个 StartPositionText 和 EndPositionText。 (例如“ThisStreet 666, 9999 City”)
以上 SQL 有效,但我想添加 StartPositionText 和 EndPositionText。 所以我需要从 w.StartDateAndTime = MIN(w.StartDateAndTime) 的行获取 StartPositionText 和行中的 EndPositionText,其中 w.EndDateAndTime = Max(w.EndDateAndTime)。 我尝试了 SELECT 但我不能在 WHERE 子句中使用 MIN(w.StartDateAndTime) 并且我无法让它与 HAVING 子句一起使用。
编辑:示例数据 tblWorkingTimes
Name | StartDateAndTime | EndDateAndTime | StartText | EndText |
---|---|---|---|---|
Jim | 2021-09-09 07:28:16 | 2021-09-09 08:28:16 | "StartPlace1" | "EndPlace1" |
Jim | 2021-09-09 08:28:16 | 2021-09-09 09:28:16 | "StartPlace2" | "EndPlace2" |
Jim | 2021-09-09 09:28:16 | 2021-09-09 10:28:16 | "StartPlace3" | "EndPlace3" |
Jim | 2021-09-09 10:28:16 | 2021-09-09 11:28:16 | "StartPlace4" | "EndPlace4" |
期望的输出
Name | StartDateAndTime | EndDateAndTime | StartText | EndText |
---|---|---|---|---|
Jim | 2021-09-09 07:28:16 | 2021-09-09 11:28:16 | "StartPlace1" | "EndPlace4" |
提前致谢
您可以为此使用 FIRST_VALUE
和 LAST_VALUE
select
w.DriverName,
convert(date, w.StartDateAndTime) as DayPerformed,
MIN(w.StartDateAndTime) as StartTime,
MAX(w.EndDateAndTime) as EndTime
StartPositionText,
EndPositionText
from (
SELECT *,
StartPositionText = FIRST_VALUE(StartPositionText) OVER (PARTITION BY w.DriverName, convert(date, w.StartDateAndTime)
ORDER BY w.StartDateAndTime ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING),
EndPositionText = LAST_VALUE(EndPositionText) OVER (PARTITION BY w.DriverName, convert(date, w.StartDateAndTime)
ORDER BY w.StartDateAndTime ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING)
FROM webfleet.tblWorkingTimes w
) w
group by w.DriverName,
convert(date, w.StartDateAndTime),
StartPositionText,
EndPositionText;
与 Charlieface 类似的 FISRT_VALUE
和 LAST_VALUE
解决方案,但更直接一些。将 CAST
的开始日期和结束日期作为日期添加到分区 by,使用多个日期清理。
DECLARE @t1 TABLE (Driver VARCHAR(50), StartDateTime DATETIME, EndDateTime DATETIME, StartPlace VARCHAR(20), EndPlace VARCHAR(20))
INSERT INTO @t1
VALUES
('Jim','2021-09-09 07:28:16','2021-09-09 08:28:16',' "StartPlace1"',' "EndPlace1"'),
('Jim','2021-09-09 08:28:16','2021-09-09 09:28:16',' "StartPlace2"',' "EndPlace2"'),
('Jim','2021-09-09 09:28:16','2021-09-09 10:28:16',' "StartPlace3"',' "EndPlace3"'),
('Jim','2021-09-09 10:28:16','2021-09-09 11:28:16',' "StartPlace4"',' "EndPlace4"'),
('Jim','2021-09-10 06:28:16','2021-09-10 08:28:16',' "StartPlace1"',' "EndPlace1"'),
('Jim','2021-09-10 08:28:16','2021-09-10 09:28:16',' "StartPlace2"',' "EndPlace2"'),
('Jim','2021-09-10 09:28:16','2021-09-10 10:28:16',' "StartPlace3"',' "EndPlace3"'),
('Jim','2021-09-10 10:28:16','2021-09-10 11:30:16',' "StartPlace4"',' "EndPlace4"')
SELECT DISTINCT
Driver,
CAST(StartDateTime AS DATE) AS 'Date',
FIRST_VALUE(StartDateTime) OVER (PARTITION BY Driver, CAST(StartDateTime AS DATE) ORDER BY StartDateTime ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS StartDateTime,
LAST_VALUE(EndDateTime) OVER (PARTITION BY Driver, CAST(EndDateTime AS DATE) ORDER BY EndDateTime ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS EndDateTime,
FIRST_VALUE(StartPlace) OVER (PARTITION BY Driver, CAST(StartDateTime AS DATE) ORDER BY StartDateTime ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS StartDateTime,
LAST_VALUE(EndPlace) OVER (PARTITION BY Driver, CAST(EndDateTime AS DATE) ORDER BY EndDateTime ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS EndDateTime
FROM @t1
Driver | Date | StartDateTime | EndDateTime | StartDateTime | EndDateTime |
---|---|---|---|---|---|
Jim | 2021-09-09 | 2021-09-09 07:28:16.000 | 2021-09-09 11:28:16.000 | "StartPlace1" | "EndPlace4" |
Jim | 2021-09-10 | 2021-09-10 06:28:16.000 | 2021-09-10 11:30:16.000 | "StartPlace1" | "EndPlace4" |