【问题标题】:Return Data for each day of week (7 records for each row)- MySQL返回一周中每一天的数据(每行 7 条记录)- MySQL
【发布时间】:2016-06-13 16:57:46
【问题描述】:

我目前的查询为我提供了选定日期的数据。我想在接下来的 7 天内从所选日期开始一周中的每一天都有一个百分比:

select distinct(shift_report.advisor), team, shift_report.date as week_commencing, SUM(shift_report.time) as total_time, round(SUM(shift_report.time)/450 * 100,2) as percentage 
from shift_report
where `date` >=20160223
AND `date`<=20160301
AND `team`=4
GROUP BY shift_report.advisor ORDER BY percentage DESC;

我想看看:

顾问 |团队 |周开始|总时间 | % 第 1 天 | % 第 2 天 | % 第 3 天,以此类推 7 天

【问题讨论】:

    标签: mysql dayofweek days


    【解决方案1】:

    您可以在 SUM 聚合函数中使用条件语句,因此每天计算:-

    SELECT shift_report.advisor, 
        shift_report.team, 
        MIN(shift_report.`date`) AS week_commencing, 
        SUM(shift_report.time) as total_time, 
        ROUND(SUM(shift_report.time)/450 * 100,2) as percentage, 
        ROUND(100 * SUM(IF(shift_report.`date` = 20160223, shift_report.time, 0)) / SUM(shift_report.time), 2) AS Day1,
        ROUND(100 * SUM(IF(shift_report.`date` = 20160224, shift_report.time, 0)) / SUM(shift_report.time), 2) AS Day2,
        ROUND(100 * SUM(IF(shift_report.`date` = 20160225, shift_report.time, 0)) / SUM(shift_report.time), 2) AS Day3,
        ROUND(100 * SUM(IF(shift_report.`date` = 20160226, shift_report.time, 0)) / SUM(shift_report.time), 2) AS Day4,
        ROUND(100 * SUM(IF(shift_report.`date` = 20160227, shift_report.time, 0)) / SUM(shift_report.time), 2) AS Day5,
        ROUND(100 * SUM(IF(shift_report.`date` = 20160228, shift_report.time, 0)) / SUM(shift_report.time), 2) AS Day6,
        ROUND(100 * SUM(IF(shift_report.`date` = 20160229, shift_report.time, 0)) / SUM(shift_report.time), 2) AS Day7,
        ROUND(100 * SUM(IF(shift_report.`date` = 20160301, shift_report.time, 0)) / SUM(shift_report.time), 2) AS Day8
    FROM shift_report
    WHERE `date` >=20160223
    AND `date`<=20160301
    AND `team`=4
    GROUP BY shift_report.advisor, 
            shift_report.team
    ORDER BY percentage DESC;
    

    编辑

    如果您只想插入 1 个日期,那么您可以这样做:-

    SELECT shift_report.advisor, 
        shift_report.team, 
        MIN(shift_report.`date`) AS week_commencing, 
        SUM(shift_report.time) as total_time, 
        ROUND(SUM(shift_report.time)/450 * 100,2) as percentage, 
        ROUND(100 * SUM(IF(shift_report.`date` = start_date, shift_report.time, 0)) / SUM(shift_report.time), 2) AS Day1,
        ROUND(100 * SUM(IF(shift_report.`date` = plus_1_date, shift_report.time, 0)) / SUM(shift_report.time), 2) AS Day2,
        ROUND(100 * SUM(IF(shift_report.`date` = plus_2_date, shift_report.time, 0)) / SUM(shift_report.time), 2) AS Day3,
        ROUND(100 * SUM(IF(shift_report.`date` = plus_3_date, shift_report.time, 0)) / SUM(shift_report.time), 2) AS Day4,
        ROUND(100 * SUM(IF(shift_report.`date` = plus_4_date, shift_report.time, 0)) / SUM(shift_report.time), 2) AS Day5,
        ROUND(100 * SUM(IF(shift_report.`date` = plus_5_date, shift_report.time, 0)) / SUM(shift_report.time), 2) AS Day6,
        ROUND(100 * SUM(IF(shift_report.`date` = plus_6_date, shift_report.time, 0)) / SUM(shift_report.time), 2) AS Day7,
        ROUND(100 * SUM(IF(shift_report.`date` = end_date, shift_report.time, 0)) / SUM(shift_report.time), 2) AS Day8
    FROM shift_report
    INNER JOIN 
    (
        SELECT '2016-02-23' AS start_date, 
                DATE_ADD('2016-02-23',INTERVAL 1 DAY ) AS plus_1_date,
                DATE_ADD('2016-02-23',INTERVAL 2 DAY ) AS plus_2_date,
                DATE_ADD('2016-02-23',INTERVAL 3 DAY ) AS plus_3_date,
                DATE_ADD('2016-02-23',INTERVAL 4 DAY ) AS plus_4_date,
                DATE_ADD('2016-02-23',INTERVAL 5 DAY ) AS plus_5_date,
                DATE_ADD('2016-02-23',INTERVAL 6 DAY ) AS plus_6_date,
                DATE_ADD('2016-02-23',INTERVAL 7 DAY ) AS end_date
    ) sub01
    WHERE `date` BETWEEN start_date AND end_date
    AND `team`=4
    GROUP BY shift_report.advisor, 
            shift_report.team
    ORDER BY percentage DESC;
    

    如果您只想在 1 个地方插入 1 个日期,则如下所示:-

    SELECT shift_report.advisor, 
        shift_report.team, 
        MIN(shift_report.`date`) AS week_commencing, 
        SUM(shift_report.time) as total_time, 
        ROUND(SUM(shift_report.time)/450 * 100,2) as percentage, 
        ROUND(100 * SUM(IF(shift_report.`date` = start_date, shift_report.time, 0)) / SUM(shift_report.time), 2) AS Day1,
        ROUND(100 * SUM(IF(shift_report.`date` = plus_1_date, shift_report.time, 0)) / SUM(shift_report.time), 2) AS Day2,
        ROUND(100 * SUM(IF(shift_report.`date` = plus_2_date, shift_report.time, 0)) / SUM(shift_report.time), 2) AS Day3,
        ROUND(100 * SUM(IF(shift_report.`date` = plus_3_date, shift_report.time, 0)) / SUM(shift_report.time), 2) AS Day4,
        ROUND(100 * SUM(IF(shift_report.`date` = plus_4_date, shift_report.time, 0)) / SUM(shift_report.time), 2) AS Day5,
        ROUND(100 * SUM(IF(shift_report.`date` = plus_5_date, shift_report.time, 0)) / SUM(shift_report.time), 2) AS Day6,
        ROUND(100 * SUM(IF(shift_report.`date` = plus_6_date, shift_report.time, 0)) / SUM(shift_report.time), 2) AS Day7,
        ROUND(100 * SUM(IF(shift_report.`date` = end_date, shift_report.time, 0)) / SUM(shift_report.time), 2) AS Day8
    FROM shift_report
    INNER JOIN 
    (
        SELECT base_start_date AS start_date, 
                DATE_ADD(base_start_date,INTERVAL 1 DAY ) AS plus_1_date,
                DATE_ADD(base_start_date,INTERVAL 2 DAY ) AS plus_2_date,
                DATE_ADD(base_start_date,INTERVAL 3 DAY ) AS plus_3_date,
                DATE_ADD(base_start_date,INTERVAL 4 DAY ) AS plus_4_date,
                DATE_ADD(base_start_date,INTERVAL 5 DAY ) AS plus_5_date,
                DATE_ADD(base_start_date,INTERVAL 6 DAY ) AS plus_6_date,
                DATE_ADD(base_start_date,INTERVAL 7 DAY ) AS end_date
        FROM
        (
            SELECT '2016-02-23' AS base_start_date
        ) sub2
    ) sub1
    WHERE `date` BETWEEN start_date AND end_date
    AND `team`=4
    GROUP BY shift_report.advisor, 
            shift_report.team
    ORDER BY percentage DESC;
    

    请注意,这两种方法都避免在 WHERE 子句中进行日期计算(否则可能会触发对每行数据的计算,而不是只为查询一次)

    【讨论】:

    • 谢谢,一旦我添加了计算 % 所需的时间,您提供的代码就起作用了。无论如何要自动化,所以输入将是开始日期,其余部分可以根据开始日期计算出来,而不必手动输入每个 - 我正在使用它进行报告并有一个传递一些数据的 GUI .
    • 您可以针对返回第一个日期并计算最后一个日期的子查询进行内部连接(因此子查询返回 1 行),然后在连接的 ON 子句中进行日期检查。然后,您可以将其他日期计算为每列的开始日期 + X 天。
    • 嗨@kickstart “开始日期”将通过 gui 输入。我希望查询做的是从该日期给我 7 天的 % 列输出。上面的查询完美运行,但我无法手动输入每个日期。感谢您在上面的评论 - 我不太确定如何按照您的建议进行操作??
    • @GrahamDrummond - 添加了一些解决方案,避免在查询之前预先计算日期。并且应该避免必须计算每一行数据的日期。
    • 感谢@kickstart,这就是我使用 base + interval 1day 等方法使其工作的方式。
    【解决方案2】:

    这行得通吗? 它有点硬编码,您可以尝试使其更复杂,但这是您可以利用的基本原则:

        SELECT advisor, team, week_commencing, total_time, 
               max(case when `date` = 20160223 then percentage end) day_1,
               max(case when `date` = 20160224 then percentage end) day_2,
               max(case when `date` = 20160225 then percentage end) day_3,
               max(case when `date` = 20160226 then percentage end) day_4,
               max(case when `date` = 20160227 then percentage end) day_5,
               max(case when `date` = 20160228 then percentage end) day_6,
               max(case when `date` = 20160229 then percentage end) day_7
        FROM (
           select distinct(shift_report.advisor) AS advisor, team,
                 shift_report.date as week_commencing, SUM(shift_report.time) as    total_time, 
                 round(SUM(shift_report.time)/450 * 100,2) as percentage 
           from shift_report
           where `date` >=20160223
             AND `date`<=20160301
             AND `team`=4
           GROUP BY shift_report.advisor ORDER BY percentage DESC
        ) your_query
       GROUP BY advisor, team, week_commencing, total_time;
    

    【讨论】:

    • 嗨@dougiehauser,谢谢你,由于某种原因,查询在以下行失败:max(case when date = 20160223 then percent end) day_1,建议字段列表中的未知列“日期”。跨度>
    • 也许是因为“日期”是一个保留字......也许尝试使用date(我的意思是,反撇号,stackoverflow 不断改变它......无论如何,我已经更新了我的答案...看看是否有帮助)
    【解决方案3】:

    感谢到目前为止的回复,我现在使用以下方法显示正确的数据:

    SELECT shift_report.advisor, 
    shift_report.team, 
    MIN(shift_report.`date`) AS week_commencing, 
    SUM(shift_report.time) as total_time, 
    ROUND(100 * SUM(IF(shift_report.`date` = 20160223, shift_report.time, 0)) / 450,2) AS Day1,
    ROUND(100 * SUM(IF(shift_report.`date` = 20160224, shift_report.time, 0)) / 450,2) AS Day2,
    ROUND(100 * SUM(IF(shift_report.`date` = 20160225, shift_report.time, 0)) / 450,2) AS Day3,
    ROUND(100 * SUM(IF(shift_report.`date` = 20160226, shift_report.time, 0)) / 450,2) AS Day4,
    ROUND(100 * SUM(IF(shift_report.`date` = 20160227, shift_report.time, 0)) / 450,2) AS Day5,
    ROUND(100 * SUM(IF(shift_report.`date` = 20160228, shift_report.time, 0)) / 450,2) AS Day6,
    ROUND(100 * SUM(IF(shift_report.`date` = 20160229, shift_report.time, 0)) / 450,2) AS Day7
    

    来自 shift_report 在哪里date >=20160223 和team=4 按 shift_report.advisor 分组 ORDER BY total_time DESC;

    无论如何我可以使用第一天并根据第一个日期输入自动执行剩余的 6 天吗?

    【讨论】:

      【解决方案4】:

      使用以下方法设法使其正常工作:

      SELECT advisor, 
      MIN(shift_report.date) AS week_commencing, 
      ROUND(100 * SUM(IF(shift_report.date = %%sdate%%, shift_report.time, 0)) / 450,2) AS Day1, 
      ROUND(100 * SUM(IF(shift_report.date = %%sdate%% + INTERVAL 1 DAY, shift_report.time, 0)) / 450,2) AS Day2, 
      ROUND(100 * SUM(IF(shift_report.date = %%sdate%% + INTERVAL 2 DAY, shift_report.time, 0)) / 450,2) AS Day3, 
      ROUND(100 * SUM(IF(shift_report.date = %%sdate%% + INTERVAL 3 DAY, shift_report.time, 0)) / 450,2) AS Day4, 
      ROUND(100 * SUM(IF(shift_report.date = %%sdate%% + INTERVAL 4 DAY, shift_report.time, 0)) / 450,2) AS Day5, 
      ROUND(100 * SUM(IF(shift_report.date = %%sdate%% + INTERVAL 5 DAY, shift_report.time, 0)) / 450,2) AS Day6, 
      ROUND(100 * SUM(IF(shift_report.date = %%sdate%% + INTERVAL 6 DAY, shift_report.time, 0)) / 450,2) AS Day7 
      FROM shift_report WHERE date >=%%sdate%% 
      %%team%% 
      GROUP BY shift_report.advisor;
      

      注意:%%sdate%% 和 %%team%% 被替换为从 php 页面传入的数据。

      【讨论】:

        猜你喜欢
        • 2018-03-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-11-02
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多