获取当月的所有日期

时间:2015-12-22 11:49:34

标签: mysql

我有桌子

userID | date | time
===================
1 | 2015-02-08 | 06:32
1 | 2015-02-08 | 05:36
1 | 2015-02-08 | 17:43
1 | 2015-02-08 | 18:00
1 | 2015-02-09 | 06:36
1 | 2015-02-09 | 15:43
1 | 2015-02-09 | 19:00
1 | 2015-02-10 | 05:36
1 | 2015-02-10 | 17:43
1 | 2015-02-10 | 18:00
2 | 2015-02-08 | 06:32
2 | 2015-02-08 | 05:36
2 | 2015-02-08 | 17:43
2 | 2015-02-08 | 18:00
2 | 2015-02-09 | 06:36
2 | 2015-02-09 | 15:43
2 | 2015-02-09 | 19:00
2 | 2015-02-10 | 05:36
2 | 2015-02-10 | 17:43
2 | 2015-02-10 | 18:00

但是我希望返回的记录数与当前月份的天数完全相同,并获得输出的最小时间和最长时间。如果当前月份有28天,并且只有两个记录,则应该带来:

userID | date | in | out
========================
1 | 2015-02-01 | |
1 | 2015-02-02 | |
1 | 2015-02-03 | |
1 | 2015-02-04 | |
1 | 2015-02-05 | |
1 | 2015-02-06 | |
1 | 2015-02-07 | |
1 | 2015-02-08 | 06:32 | 18:00
1 | 2015-02-09 | 06:36 | 19:00
1 | 2015-02-10 | 05:36 | 18:00
1 | 2015-02-11 | |
1 | 2015-02-12 | |
1 | 2015-02-13 | |
1 | 2015-02-14 | |
1 | 2015-02-15 | |
1 | 2015-02-16 | |
1 | 2015-02-17 | |
1 | 2015-02-18 | |
1 | 2015-02-19 | |
1 | 2015-02-20 | |
1 | 2015-02-21 | |
1 | 2015-02-22 | |
1 | 2015-02-23 | |
1 | 2015-02-24 | |
1 | 2015-02-25 | |
1 | 2015-02-26 | |
1 | 2015-02-27 | |
1 | 2015-02-28 | |

如何修改我的查询以达到上述效果?
这是我的疑问:

$sql = "SELECT 
                    colUserID, 
                    colDate, 
                    if(min(colJam) < '12:00:00',min(colJam), '') as in, 
                    if(max(colJam) > '12:00:00',max(colJam), '') as out
                FROM tb_kehadiran
                    WHERE colDate > DATE_ADD(MAKEDATE($tahun, 31),
                    INTERVAL($bulan-2) MONTH)
                    AND
                    colDate < DATE_ADD(MAKEDATE($tahun, 1),
                    INTERVAL($bulan) MONTH)
                    AND
                    colUserID = $user_id
        GROUP BY colUserID,colDate";

5 个答案:

答案 0 :(得分:0)

我不得不考虑这一个。但到目前为止可能是最简单的答案:

WITH AllMonthDays as (
    SELECT n = 1
    UNION ALL
    SELECT n + 1 FROM AllMonthDays WHERE n + 1 <= DAY(EOMONTH(GETDATE())) 
)

SELECT 
    DISTINCT datefromparts(YEAR(GETDATE()), MONTH(GETDATE()), n) As dates
    , MIN(d.time) as 'In'
    , MAX(d.time) as 'Out'
FROM AllMonthDays as A
    LEFT OUTER JOIN
    table as d on 
        DAY(d.date) = A.n
GROUP BY n,(d.date);

---在这种环境下测试并尝试:---

use Example;
CREATE TABLE demo (
     ID int identity(1,1)
    ,date date
    ,time time
    );

INSERT INTO demo (date, time) VALUES 
    ('2015-12-08', '06:32'),
    ('2015-12-08', '05:36'),
    ('2015-12-08', '17:43'),
    ('2015-12-08', '18:00'),
    ('2015-12-09', '06:36'),
    ('2015-12-09', '15:43'),
    ('2015-12-09', '19:00'),
    ('2015-12-10', '05:36'),
    ('2015-12-10', '17:43'),
    ('2015-12-10', '18:00')
    ;

WITH AllMonthDays as (
    SELECT n = 1
    UNION ALL
    SELECT n + 1 FROM AllMonthDays WHERE n + 1 <= DAY(EOMONTH(GETDATE())) 
)

SELECT 
    DISTINCT datefromparts(YEAR(GETDATE()), MONTH(GETDATE()), n) As dates
    , MIN(d.time) as 'In'
    , MAX(d.time) as 'Out'
FROM AllMonthDays as A
    LEFT OUTER JOIN
    demo as d on 
        DAY(d.date) = A.n
GROUP BY n,(d.date);

DROP table demo;

答案 1 :(得分:0)

过去我解决这个问题的方法是拥有一个日期表,该日期表预先填充了几年。

你可以创建这样一个表,可能用年,月和月的索引定义年,月和日的列。

然后,您可以将此表与数据一起使用,以确保结果中包含所有日期。

答案 2 :(得分:-1)

你需要三件事:

  • 日期列表。
  • 左连接
  • 聚合

所以:

select d.dte, min(t.time), max(t.time)
from (select date('2015-02-01') as dte union all
      select date('2015-02-02') union all
      . . 
      select date('2015-02-28')
     ) d left join
     t
     on d.dte = t.date
group by d.dte
order by d.dte;

答案 3 :(得分:-1)

试试这个

set @is_first_date = 0;
set @temp_start_date =  date('2015-02-01');
set @temp_end_date =  date('2015-02-28');

select my_dates.date,your_table_name.user_id, MIN(your_table_name.time), MAX(your_table_name.time)  from 
( select if(@is_first_date , @temp_start_date := DATE_ADD(@temp_start_date, interval 1 day), @temp_start_date) as date,@is_first_date:=@is_first_date+1    as start_date from information_schema.COLUMNS 
where @temp_start_date < @temp_end_date limit 0, 31
) my_dates left join your_table_name on 
my_dates.date = your_table_name.date
group by my_dates.date

答案 4 :(得分:-4)

尝试此查询

 SELECT `date`, MIN(`time`) as `IN`, MAX('time') AS `OUT` 
   FROM `table_name` WHERE month(current_date) = month(`date`)
   GROUP BY `date`;