我在SQL Server中有一个表,其中记录了个人输入和输出。 同一天有多个小时的进入或退出。我需要的是恢复当天的第一个入口和最后一个出口。
Date hour Clock
------------------------
01/01/2017 09:00 1
01/01/2017 11:30 2
01/01/2017 17:00 2
02/01/2017 7:59 1
02/01/2017 16:00 1
我有这个SQL查询可以正常工作。
SELECT
d.Date,
MIN(d.hour) as Entry,
MAX(dt.hour) as Exit
FROM
#temp1 AS d
LEFT JOIN
#temp1 AS dt ON d.Date = dt.Date
GROUP BY
d.Date
ORDER BY
Date DESC
但如果我在查询中再添加2列
SELECT
d.Date,
d.clock as ClockEntry, -- Aggregated column to display
MIN(d.hour) as Entry,
dt.clock as ClockExit, -- Aggregated column to display
MAX(dt.hour) as Exit
FROM
#temp1 AS d
LEFT JOIN
#temp1 AS dt ON d.Date = dt.Date
GROUP BY
d.Date
ORDER BY
Date DESC
我收到此错误:
专栏'#temp1.clock'在选择列表中无效,因为它不包含在聚合函数或GROUP BY子句中。
我只需按字段分组"日期",我不想为GROUP BY
添加更多条件..我怎么能解决它?
我想要这个结果
DATE ClockEntry Entry ClockExit Exit
-------------------------------------------------------
01/01/2017 1 09:00 2 17:00
02/01/2017 1 7:59 1 16:00
答案 0 :(得分:1)
所以有一种简单的方法可以做到这一点 - 使用2个排名功能:
此时,可以将行连接在一起,它们的值均为1,并且日期匹配。
我倾向于使用CTE:
with temp2 (MinId, MaxId, Date, Hour, Clock)
AS
(
select ROW_NUMBER() Over (partition by date order by hour),
ROW_NUMBER() Over (partition by date order by hour desc),
*
from temp1
)
select distinct
d1.Date,
d1.Clock,
d1.Hour,
d2.Clock,
d2.Hour
FROM temp2 d1
LEFT JOIN temp2 d2
ON d1.Date = d2.Date -- dates match
AND d1.MinId=d2.MaxId -- minId=earliest record MaxId=latest record
WHERE d1.MinId=1
答案 1 :(得分:-1)
如果您知道只有一个值会出现clock
列,
只需使用MAX
或MIN
聚合函数汇总值,例如:
SELECT
d.Date,
MIN(d.clock) as ClockEntry,
MIN(d.hour) as Entry,
MAX(dt.clock) as ClockExit,
MAX(dt.hour) as Exit
FROM #temp1 AS d
LEFT JOIN #temp1 AS dt
ON d.Date= dt.Date
GROUP BY d.Date
order by Date desc
或者,如果您有多个时钟值并希望全部看到它们,
将它们添加到GROUP BY
语句中:
SELECT
d.Date,
d.clock as ClockEntry,
MIN(d.hour) as Entry,
dt.clock as ClockExit,
MAX(dt.hour) as Exit
FROM #temp1 AS d
LEFT JOIN #temp1 AS dt
ON d.Date= dt.Date
GROUP BY d.Date, d.clock, dt.clock
order by Date desc
每个日期使用cursor或Common Table Expression来获得第一个条目和最后一个条目。
指定日期的首次参赛
SELECT TOP 1 d.date, d.clock as ClockEntry, d.hour as Entry
FROM #temp1 AS d
WHERE d.date = @myDate
ORDER BY d.hour ASC
指定日期的最后一次退出
SELECT TOP 1 d.date, d.clock as ClockExit, d.hour as Exit
FROM #temp1 AS d
WHERE d.date = @myDate
ORDER BY d.hour DESC