合并MySQL中的查询

时间:2015-04-14 01:37:37

标签: php mysql

正如您在下面看到的那样,我得到了这个查询,它可以获得批准某些特定表单所需时间的平均值。我通过提供日期范围进行过滤,日期范围只需要包含使用日历表的工作日(周一至周五)。

SELECT 
fg2.form_descr AS 'form_description',

CONCAT(
    FLOOR(HOUR(SEC_TO_TIME(AVG(TIMESTAMPDIFF(SECOND, submitted, viewed)))) / 24), ' days ',
    MOD(HOUR(SEC_TO_TIME(AVG(TIMESTAMPDIFF(SECOND, submitted, viewed )))), 24), ' hours ',
    MINUTE(SEC_TO_TIME(AVG(TIMESTAMPDIFF(SECOND, submitted, viewed)))), ' minutes'
) AS 'Average Approval Time',

COUNT(user_forms.form_id) AS ' number_of_forms'

FROM

forms.user_forms,
forms.forms,
forms.form_groups fg,
forms.form_groups fg2

WHERE
    user_forms.form_id = forms.form_id
    AND forms.form_group = fg.form_group_id
    AND fg.approver_group = fg2.form_group_id
    AND viewed > submitted
    AND submitted BETWEEN '2015-01-01' AND '2015-06-30'

GROUP BY 
    fg.approver_group

结果如下:

form_description      Average Approval Time         number_of_forms

'Log In'             '1 days 2 hours 04 minutes'    '35'
'Programming'        '2 days 5 hours 22 minutes'    '100'
...and so on

现在,我有一个名为Calendar的表,它包含两列。一个是日期,另一个是is_holiday,没有主要ID和/或外键。 Calendar表只是一个日期列表,告诉您它是否是假日。 例如:

Date           is_holiday

'2014-01-01'   '0'
'2014-01-02'   '0'
'2014-01-03'   '0'
and so on...

SELECT date 
FROM calendar
WHERE DAYOFWEEK(date) NOT IN (1,7) 
AND date BETWEEN '2015-01-01' AND '2015-06-30'
AND is_holiday = 0

如何将这两个查询合并在一起?我尝试在FROM子句中使用两个子查询,但我似乎无法得到这个。是的,我确实试过环顾四周,但我无法做到这一点。

2 个答案:

答案 0 :(得分:1)

您应该可以通过加入日历表来获得所需内容。这样的事情可能会这样做:

 SELECT 
    fg2.form_descr AS 'form_description',

    CONCAT(
        FLOOR(HOUR(SEC_TO_TIME(AVG(TIMESTAMPDIFF(SECOND, submitted, viewed)))) / 24), ' days ',
        MOD(HOUR(SEC_TO_TIME(AVG(TIMESTAMPDIFF(SECOND, submitted, viewed )))), 24), ' hours ',
        MINUTE(SEC_TO_TIME(AVG(TIMESTAMPDIFF(SECOND, dateSubmitted, viewed)))), ' minutes'
    ) AS 'Average Approval Time',

    COUNT(user_forms.form_id) AS ' number_of_forms'

    FROM

    forms.user_forms,
    forms.forms,
    forms.form_groups fg,
    forms.form_groups fg2
    forms.calendar c

    WHERE
        user_forms.form_id = forms.form_id
        AND forms.form_group = fg.form_group_id
        AND fg.approver_group = fg2.form_group_id
        AND c.`date` = date(viewed)
        AND viewed > submitted
        AND viewed BETWEEN '2015-01-01' AND '2015-06-30'
        AND dayofweek(viewed) NOT IN (1,7)
        AND c.is_holiday = 0

GROUP BY 
    fg.approver_group

这应该排除任何被查看过的行'无论是度假还是周末。

当然,除非您想要做的是从这些计算中排除任何假日或周末的日子:TIMESTAMPDIFF(SECOND, submitted, viewed)在这种情况下它是一个完全不同的鱼。

假设在周末或公共场所(大假设)中从未提交或查看表单,您需要做的就是减去属于该类别的天数,并在提交和查看之间进行。这应该这样做。

     SELECT 
            fg2.form_descr AS 'form_description',

            CONCAT(
                FLOOR(
                  HOUR(SEC_TO_TIME(
                    AVG(
                      TIMESTAMPDIFF(SECOND, submitted, viewed)))) / 24) -
                      (SELECT(COUNT(*) 
                         FROM calendar 
                         WHERE `date` BETWEEN submitted AND viewed 
                           AND (DAYOFWEEK(`date`) in (1,7) 
                             OR is_holiday = 1)
                      ), ' days ',
                MOD(HOUR(SEC_TO_TIME(AVG(TIMESTAMPDIFF(SECOND, submitted, viewed )))), 24), ' hours ',
                MINUTE(SEC_TO_TIME(AVG(TIMESTAMPDIFF(SECOND, dateSubmitted, viewed)))), ' minutes'
            ) AS 'Average Approval Time',
   COUNT(user_forms.form_id) AS ' number_of_forms'

        FROM

        forms.user_forms,
        forms.forms,
        forms.form_groups fg,
        forms.form_groups fg2
        forms.calendar c

        WHERE
            user_forms.form_id = forms.form_id
            AND forms.form_group = fg.form_group_id
            AND fg.approver_group = fg2.form_group_id
            AND c.`date` = date(viewed)
            AND viewed > submitted
            AND viewed BETWEEN '2015-01-01' AND '2015-06-30'    
    GROUP BY 
        fg.approver_group

here is a demo查询一些假数据,显示该理论是如何运作的。它应该适用于你正在做的事情。

答案 1 :(得分:1)

这是未经测试的,但应该有效。我使用[ ... ]将代码缩短为新片段 - 保留原始查询原样。

SELECT
    [ ... ],
    is_holiday

FROM
    [ ... ],
    calendar ON calendar.Date = viewed

WHERE
    [ ... ]
    AND calendar.Date = viewed

GROUP BY
    [ ... ]

基本上,您只是加入日期匹配的calendar表格并抓取相应的is_holiday字段。

如果您专注于假期,请AND calendar.Date <> '0'之后使用AND calendar.Date = '0'(如果您想要非假期,请使用calendar.Date = viewed

此外,您不需要查找表来确定日期是否为周末 - 它与第一个表中的日期相同。

DAYOFWEEK(viewed) NOT IN (1,7)

修改

这是完全的。

SELECT 
fg2.form_descr AS 'form_description',

CONCAT(
    FLOOR(HOUR(SEC_TO_TIME(AVG(TIMESTAMPDIFF(SECOND, submitted, viewed)))) / 24), ' days ',
    MOD(HOUR(SEC_TO_TIME(AVG(TIMESTAMPDIFF(SECOND, submitted, viewed )))), 24), ' hours ',
    MINUTE(SEC_TO_TIME(AVG(TIMESTAMPDIFF(SECOND, submitted, viewed)))), ' minutes'
) AS 'Average Approval Time',

COUNT(user_forms.form_id) AS ' number_of_forms',
is_holiday

FROM

forms.user_forms,
forms.forms,
forms.form_groups fg,
forms.form_groups fg2,
calendar ON calendar.Date = viewed

WHERE
    user_forms.form_id = forms.form_id
    AND forms.form_group = fg.form_group_id
    AND fg.approver_group = fg2.form_group_id
    AND viewed > submitted
    AND submitted BETWEEN '2015-01-01' AND '2015-06-30'
    AND calendar.Date = viewed
    AND is_holiday = '0'
    AND DAYOFWEEK(calendar.Date) NOT IN (1,7)

GROUP BY 
    fg.approver_group