简体   繁体   English

获取当月的所有日期

[英]get all dates in the current month

i have table 我有桌子

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

But i want the number of records returned to be exactly the same as the number of days of the current month and get min time for in and max time for the out. 但是我希望返回的记录数与当前月份的天数完全相同,并获得输入的最小时间和输出的最大时间。 if the current month has 28 days and only had two records it should bring: 如果当前月份有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 | |

How can i modify my query to achieve the above result? 如何修改查询以达到上述结果?
this is my query: 这是我的查询:

$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";

I had to think about this one. 我不得不考虑这一点。 But probably the simpliest answer so far: 但到目前为止可能是最简单的答案:

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);

--- Test and tried in this environment: --- ---在这种环境下进行测试:-

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;

The way I've approached this problem in the past is to have a date table that is pre-populated for some years in the future. 我过去处理此问题的方式是在未来几年中预先填充日期表。

You could create such a table, possibly defining columns for year, month and date, with indexes on year and month. 您可以创建这样的表,可能定义年,月和日期的列,并以年和月为索引。

You can then use this table with a JOIN on your data to ensure that all dates are present in your results. 然后,可以将该表与数据上的JOIN一起使用,以确保结果中包含所有日期。

You need three things: 您需要三件事:

  • A list of dates. 日期列表。
  • A left join 左联接
  • Aggregation 聚合

So: 所以:

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;

Try this 尝试这个

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

Try This query 试试这个查询

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM