Mysql-使用DAYOFWEEK在特定日期每小时范围内的行

Mysql-使用DAYOFWEEK在特定日期每小时范围内的行,mysql,Mysql,我正在尝试获取一个查询,该查询将返回一个结果集,根据日期的dayofweek,该结果集的总读取时间在特定的小时范围内(在工作时间表中定义),其结果如下所示: working | nonworking | weekend | date | group_id ----------------------------------------------------------------- 50.3 | 30.8 | 0 | 2015-04-01

我正在尝试获取一个查询,该查询将返回一个结果集,根据日期的
dayofweek
,该结果集的总读取时间在特定的小时范围内(在
工作时间
表中定义),其结果如下所示:

working | nonworking | weekend | date              | group_id
-----------------------------------------------------------------
50.3    | 30.8       | 0       | 2015-04-01 00:00  | 7
40.3    | 60.8       | 0       | 2015-04-01 00:00  | 8
50.3    | 30.8       | 0       | 2015-04-02 00:00  | 7
40.3    | 60.8       | 0       | 2015-04-02 00:00  | 8
工作时间和周末时间范围存储在数据库中的
工作时间
,暗示非工作时间范围(
基本上不在当天的其他时间范围之间)

各表如下:

读数表包含每小时读数,名为
读数

group_id     | reading     | datestamp         
------------------------------------------------------
7            | 30.8        | 2015-04-01 00:00  
7            | 20.2        | 2015-04-01 01:00  
7            | 11.2        | 2015-04-02 00:00  
7            | 20.2        | 2015-04-02 01:00  
8            | 26.2        | 2015-04-01 00:00  
8            | 30.2        | 2015-04-01 01:00  
8            | 26.2        | 2015-04-02 00:00  
8            | 30.2        | 2015-04-02 01:00  
小时范围存储在
working_hours
表中,day列为
dayOfWeek
格式(1=星期日,2=星期一等):

日类型在
工作时数\u日类型表中,对于我来说,事情变得复杂,工作日和周末只有一个范围,但开始/结束周末有两个范围(“开始周末”第一个范围是工作时数,第二个范围是周末时数,“结束周末”第一个范围是周末时数,第二个范围是工作时数)

范围类型在
工作时间范围类型表中:

id | type
------------------
1  | Working
2  | Weekend

我的Mysql知识仅限于简单的
SELECT
INSERT
等以及
JOIN
s的基础知识-我已经了解了
HOUR(日期戳)8到14之间
但不知道如何让子查询在父查询中使用
在“2015-04-01 00:00:00”和“2015-04-02 23:59:00”之间的日期戳进行迭代
如果事实上是这样做的…

我不完全清楚什么是工作时间还是非工作时间,但这是否有效

SELECT
 sum(CASE WHEN rtype.range_type_id = 1 THEN reading ELSE 0 END) AS working
 sum(CASE WHEN rtype.range_type_id = 2 THEN reading ELSE 0 END) AS nonworking
 CASE WHEN r1.daynum in (7,1) THEN 1 ELSE 0 END as weekend
 date(datestamp) as date
 r1.group_id 
FROM
    (SELECT
        group_id,
        reading,
        time(datestamp) as rTime,
        case when weekday(datestamp) = 0 THEN 2 #weekday() monday to working hours monday
            when weekday(datestamp) = 1 THEN 3 
            when weekday(datestamp) = 2 THEN 4 
            when weekday(datestamp) = 3 THEN 5 
            when weekday(datestamp) = 4 THEN 6 
            when weekday(datestamp) = 5 THEN 7 
            when weekday(datestamp) = 6 THEN 1 
        else NULL
        END CASE AS daynum
    FROM readings) AS r1
    LEFT JOIN working_hours w1
        ON (r1.daynum = w1.day) 
         AND (r1.group_id = w1.group_id) 
         AND (r1.rTime BETWEEN w1.range_start AND w1.range_end)
    LEFT JOIN working_hours_day_type dtype 
        ON w1.day_type_id = dtype.id 
    LEFT JOIN working_hours_range_type rtype
        ON w1.range_type_id = rtype.id
GROUP BY
 CASE WHEN daynum in (7,1) THEN 1 ELSE 0 END,
 date(datestamp) as date,
 r1.group_id

对不起,你把我弄丢了。这似乎是一个过于复杂的设计——还是我遗漏了什么?如果列与问题无关,则不要包含它们。欢迎提出任何简化建议,我需要在指定范围内获得每日使用情况的明细(
SUM
)。如果4月1日是星期日,然后查看
working_hours
获取特定于周日的任何范围,并将其应用于该日期的读数以获得总数。这不需要额外的表格-您可以在第一次选择中使用两个案例语句来完成所有这些。您的示例中似乎缺少第8组的工作时间data@bf2020关心在回答中演示?:)谢谢你的回答,它给了我完成这件事所需要的一切!我没有暗指非工作时间,而是为他们创建了一个范围类型(不能加入暗指数据!),它简化了大量查询:-为了得到我需要的东西,去掉了很多-不确定你是否想编辑你的内容,以便我可以将其标记为正确?(有一些拼写错误等)我很高兴它能起作用,因为你可以看到它比我最初对你的问题的评论中想象的要复杂得多。。。我打算根据你的评论修改答案,但是当我尝试加载它时,链接导致404错误。我可以进一步解释或评论SQL正在做什么吗?
id | type
------------------
1  | Working
2  | Weekend
SELECT
 sum(CASE WHEN rtype.range_type_id = 1 THEN reading ELSE 0 END) AS working
 sum(CASE WHEN rtype.range_type_id = 2 THEN reading ELSE 0 END) AS nonworking
 CASE WHEN r1.daynum in (7,1) THEN 1 ELSE 0 END as weekend
 date(datestamp) as date
 r1.group_id 
FROM
    (SELECT
        group_id,
        reading,
        time(datestamp) as rTime,
        case when weekday(datestamp) = 0 THEN 2 #weekday() monday to working hours monday
            when weekday(datestamp) = 1 THEN 3 
            when weekday(datestamp) = 2 THEN 4 
            when weekday(datestamp) = 3 THEN 5 
            when weekday(datestamp) = 4 THEN 6 
            when weekday(datestamp) = 5 THEN 7 
            when weekday(datestamp) = 6 THEN 1 
        else NULL
        END CASE AS daynum
    FROM readings) AS r1
    LEFT JOIN working_hours w1
        ON (r1.daynum = w1.day) 
         AND (r1.group_id = w1.group_id) 
         AND (r1.rTime BETWEEN w1.range_start AND w1.range_end)
    LEFT JOIN working_hours_day_type dtype 
        ON w1.day_type_id = dtype.id 
    LEFT JOIN working_hours_range_type rtype
        ON w1.range_type_id = rtype.id
GROUP BY
 CASE WHEN daynum in (7,1) THEN 1 ELSE 0 END,
 date(datestamp) as date,
 r1.group_id