【问题标题】:mysql - query to find SUM accrued per hour per daymysql - 查询以查找每天每小时累积的 SUM
【发布时间】:2013-06-17 15:51:37
【问题描述】:

我正在尝试创建一个查询,该查询将累积全天 24 小时轮班的员工人数。因此,当用户从 2013 年 6 月 17 日 10:00:00 开始并结束 14:00:00 轮班时,我希望用户在 5 个单元格中“计数”

2013-06-17 10 : +1 here
2013-06-17 11 : +1 here
2013-06-17 12 : +1 here
2013-06-17 13 : +1 here
2013-06-17 14 : +1 here

这最终应该会为我提供 24 小时的范围,显示在特定时间有多少员工在工作。

我有 3 个我使用的表。

teamslots
---------
id
startdate
starttime
endtime

teamslot_schedule
-----------------
id
slotid (joins to is in teamslots)
userid

shifthours
----------
thehour

在轮班时间,我有 24 条记录 - 0 - 23 条记录,每小时需要一条。

然后我尝试在 HOUR(teamslots.starttime) 和 GROUP BY startdate,thehour 上离开,但没有真正的运气。

这是我的查询(当前返回 24 行的小时,空,空)

SELECT a.thehour,b.startdate,b.taken FROM shifthours a LEFT JOIN (SELECT startdate,starttime,endtime,count(DISTINCT b.id) as taken FROM teamslots a
LEFT JOIN teamslot_schedule b ON a.id=b.slotid) b ON a.thehour=HOUR(b.starttime)
GROUP BY b.startdate,a.thehour;

有人可以帮我吗?指出正确的方向吗?

【问题讨论】:

  • 请在SQL Fiddle 上设置您的示例架构和测试数据,以便我们为您提供您可以执行的答案,而无需我们重复设置。

标签: mysql


【解决方案1】:

简单的想法。想出相关日期的时间范围(假设这一天是查询提前知道的)并在开始时间和结束时间之间进行 JOIN。

像这样:-

SELECT DATE_ADD('2013/06/17', INTERVAL thehour HOUR), COUNT(teamslot_schedule.id)
FROM shifthours
LEFT OUTER JOIN teamslots
ON DATE_ADD('2013/06/17', INTERVAL thehour HOUR) BETWEEN starttime AND starttime AND endtime
LEFT OUTER JOIN teamslot_schedule
ON teamslots.id = teamslot_schedule.slotid
GROUP BY DATE_ADD('2013/06/17', INTERVAL thehour HOUR)

请注意,这不会直接奏效,因为我不确定您的开始时间/结束时间与开始日期的关系。

【讨论】:

  • 差不多了 - 谢谢 Kickstart :D 从 shifthours 中选择 a.thehour,b.startdate,COUNT(DISTINCT c.id) a LEFT JOIN teamslots b ON a.thehour BETWEEN HOUR(b. starttime) AND HOUR(b.endtime) LEFT JOIN teamslot_schedule c ON b.id=c.slotid WHERE YEAR(b.startdate) = YEAR(now()) GROUP BY b.startdate,a.thehour; 只有我不知道没有员工工作的时间。有什么想法吗?
  • 您已经放置了一个 WHERE 子句来检查 b.startdate 列,但这意味着 b 上的 LEFT OUTER JOIN 将作为 INNER JOIN 工作(即,如果没有匹配的行b.startdate 的年份永远不能等于当前年份)。如果您想检查(我假设是月份等),那么将 WHERE 子句中的检查放在连接的 ON 子句中。您能否发布一些示例数据以及您希望如何处理与开始时间/开始日期不同的一天的结束时间(或者您是否在团队槽中也有结束日期字段?)。
【解决方案2】:

以下查询将包括无人工作时的几个小时的存储桶:

SELECT
    DATE_FORMAT(d.startdate + INTERVAL s.thehour HOUR, '%Y-%m-%d %H') AS date,
    COUNT(DISTINCT ts.userid) AS users
FROM
    shifthours s
JOIN
    (SELECT DISTINCT startdate FROM teamslots) d
LEFT JOIN
    teamslots t ON t.startdate = d.startdate AND
        s.thehour BETWEEN HOUR(t.starttime) AND HOUR(t.endtime)
LEFT JOIN
    teamslot_schedule ts ON ts.slotid = t.id
GROUP BY
    d.startdate,
    s.thehour
ORDER BY
    d.startdate + INTERVAL s.thehour HOUR;

有关工作示例,请参阅http://sqlfiddle.com/#!2/4a716/13

以下查询将仅包含有人工作时的行:

SELECT
    DATE_FORMAT(t.startdate + INTERVAL s.thehour HOUR, '%Y-%m-%d %H') AS date,
    COUNT(DISTINCT ts.userid) AS users
FROM
    shifthours s
INNER JOIN
    teamslots t ON s.thehour BETWEEN HOUR(t.starttime) AND HOUR(t.endtime)
LEFT JOIN
    teamslot_schedule ts ON ts.slotid = t.id
GROUP BY
    t.startdate,
    s.thehour
ORDER BY
    t.startdate + INTERVAL s.thehour HOUR;

有关工作示例,请参阅http://sqlfiddle.com/#!2/4a716/15

【讨论】:

  • 感谢您的代码和示例。只有当我将它应用到我的数据时,我才知道没有员工工作的时间。 [代码] SELECT a.thehour,b.startdate,COUNT(c.id) as taken FROM shifthours a LEFT JOIN teamslot b ON a.thehour BETWEEN HOUR(b.starttime) AND HOUR(b.endtime) LEFT JOIN teamslot_schedule c ON b.id=c.slotid WHERE b.fid=67 AND YEAR(b.startdate) = YEAR(now()) GROUP BY b.startdate,a.thehour ORDER BY b.startdate,a.thehour; [/code](实在搞不懂这里的格式:()
  • 要包含没有人工作的时间,您需要在初始查询“外部”包含WHERE。这是示例:sqlfiddle.com/#!2/4a716/30
猜你喜欢
  • 2020-04-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多