I have table - attendance
staff_id | in_date | out_date | shift_in | shif_out | in_time | out_time
1 2013-09-10 2013-09-10 06-30-00 15-00-00 07-00-00 15-00-00
2 2013-09-10 2013-09-11 20-00-00 06-00-00 19-00-00 06-00-00
3 2013-09-10 2013-09-11 23-00-00 06-00-00 23-30-00 07-00-00
I need to get result as
staff_id | late_time | early_time | extra_time
1 00-30-00 00-00-00 00-00-00
2 00-00-00 01-00-00 00-00-00
2 00-30-00 00-00-00 01-00-00
Can I achieve the result from mysql query itself or Do I need to use PHP to calculate this ? How can I get this result ?
First of all I would use "DATETIME" in one Column instead of having a DATE column and a TIME column - this makes it easier to compare the Dates and get differences.
Then use "TIMEDIFF()" to compare the times to get the difference.
If your DB-Layout is already set, use ADDTIME to combine the different columns into one DATETIME column like this:
SELECT TimeDiff(AddTime(in_date,shift_in), AddTime(out_date,in_time)) AS late_time
Related
I have a table Schedule with 3 columns (id, ref_number, pay_date). Each ref_number has a pay_date in every month. So the table looks something like this:
id | ref_number | pay_date
-----------------------------
1 | A001 | 2018-06-29
1 | A001 | 2018-07-29
1 | A002 | 2018-06-30
1 | A002 | 2018-07-30
1 | A002 | 2018-08-30
1 | A003 | 2018-06-29
I want to fetch only the earliest record for every ref_number that have pay_date between today and a date (30 or 31 days from today). The below query works fine in Mysql (I would pass the dates dynamically later).
SELECT id,ref_number,MIN(pay_date) FROM schedule
WHERE (pay_date BETWEEN '2018-06-30' AND '2018-07-30')
GROUP BY ref_number
I know we can turn the mysql "strict" to false in Database config file and the Group By would behave as expected, but without having to change that is there any other way around this problem?
What would be the eloquent equivalent for this query? With or without groupby.
After searching for a while, I came across an answer using nested select statement and gave it a try in Laravel. It worked exactly as I wanted. Here's the sweet piece of code:
Schedule::select(DB::raw(id, ref_number, MIN(pay_date) as pay_date))
->from(DB::raw("(SELECT *
FROM schedule
WHERE (pay_date > CURDATE()))
temp")
)
->groupBy('temp.ref_number')
->get();
In my MySql DB I have these fields:
id | email_id | interval | start_at | last_sent_at
--- | -------- | ---------- | ------------------- | -------------------
1 | 8293 | +6 months | 2017-06-14 16:59:54 | 2017-06-14 16:59:54
--- | -------- | ---------- | ------------------- | -------------------
2 | 8904 | (NULL) | 2017-05-14 12:32:45 | (NULL)
I am trying to create a dynamic way for users to set a schedule for an email job in laravel. The idea is to use laravel's commands scheduler to run a command that checks all scheduled emails and then runs them if they haven't been sent (whereNull(last_sent_at)) or if the last time they were sent was more than the current time minus 6 months or 12 months or what ever they select for that field.
I have tried several different queries to get this to work to no avail. In laravelized code I have tried the following...
$schedules = Schedule::selectRaw('schedules.schedulable_id, schedules.schedulable_type, UNIX_TIMESTAMP(NOW()) - UNIX_TIMESTAMP(schedules.interval) as NowPlusInterval')
->whereNull('last_sent_at')
->orWhere('schedules.last_sent_at', '>=', 'NowPlusInterval')
->get();
and
$schedules = Schedule::whereNull('last_sent_at')
->orWhereRaw('schedules.last_sent_at >= NOW()-'.Carbon::parse('schedules.interval')->toDateTimeString())
->get();
and many many other variations. The second one is the simplest to me but because I am passing the db field to a php function it doesn't recognize that I am trying to get the value from the db field (not parse a string called 'schedules.interval'). Is there anyway write this field into a variable that Carbon can parse or is there a raw mysql query that I can run that will give me all the fields where last_sent_at is null and where now minus the interval listed is more than the last_sent_at.
I've racked my brain on this for hours. Any help is appreciated.
Try using mysql's DATE_SUB() and INTERVAL functions. Something to the effect of:
->whereRaw('last_sent_at >= SUB_DATE(NOW(), INTERVAL 6 MONTH)')
or perhaps this:
->whereNull('last_sent_at')
->orWhere(DB::raw('DATE(`schedules.last_sent_at`) >= DATE_SUB(NOW(), INTERVAL `schedules.interval`')))
->get();
This is the table:
+----+-----------+------------+----------+
| id | id_sensor | start_time | end_time |
+----+-----------+------------+----------+
| 1 | 12 | 21:15:00 | 02:45:00 |
| 2 | 7 | 00:00:00 | 23:15:00 |
| 3 | 5 | 04:30:00 | 16:30:00 |
+----+-----------+------------+----------+
I need to get record(s) where a specific time (e.g. 01:00:00) passed by PHP is between. start_time and end_time are TIME fields in UTC, I'm passing to the query hour via php, note, converted in php from user_timezone to UTC.
SELECT * FROM test WHERE TIME('01:00:00') BETWEEN start_time AND end_time;
Query returns only record id 2, not the 1. I need both, in this case (for id 1, end time ofcourse is next day).
Of course, if we looking for TIME('01:00:00'), we don't need the id 3.
Thank you.
I think this is the logic you want:
SELECT *
FROM test
WHERE (start_time < end_time AND TIME('01:00:00') BETWEEN start_time AND end_time) OR
(start_time > end_time AND TIME('01:00:00') NOT BETWEEN end_time AND start_time);
now() returns both, current time and date. You can also work with curtime(), which returns only the current time.
BTW, i think that working with SELECT * should be avoided (maybe you used it just for this example), it is IMHO always better to list the fields needed explicitly.
I am not really sure how to explain this, but basically what I am trying to do is get the average time that it takes between a set of dates. This is what the database table looks like
id | offer_id | user | date | date_completed
----------------------------------------------------
1 | 123 | test | 1352265988 | 1352265995
2 | 123 | admin| 1352266004 | 1352266022
3 | 123 | kira | 1352264754 | 1352271946
I need to get the average time between the 2 timestamps and calculate them together so I can echo it out in my code. I am sure this would be done with a foreach statement, but I have no idea how to go about doing it. If there is anyone that can point me in the right direction that would be great!
Unless I'm missing something, you can just do it in a single query:
SELECT AVG(date_completed - date)
FROM myTable
Use the SQL-function AVG for each of the colums (date and date_completed). Than, you can just substract each average time and you will get your result you are searching for.
I have a MySQL table that looks something like this:
+-----+------------+
| id | enddate |
+------------------+
| 1 | 2012-06-30 |
+------------------+
| 2 | 2012-07-05 |
+------------------+
| 3 | 2012-07-02 |
+------------------+
On my website I would like to print out all rows who has a date that is between the range:Today's date (I mean not fixed, but the date when the query is beeing run) and 2 weeks ahead.So, using the above example only row 1 and 3 would be printed.Anyone got a solution for this?
I think you need the BETWEEN comparison operator and some simple date functions:
WHERE enddate BETWEEN CURDATE() AND ADDDATE(CURDATE(), INTERVAL 14 DAY);
http://dev.mysql.com/doc/refman/5.5/en/comparison-operators.html#operator_between
http://dev.mysql.com/doc/refman/5.5/en/date-and-time-functions.html#function_adddate
You can use
WHERE enddate BETWEEN CURDATE() AND ADDDATE(CURDATE(), INTERVAL 2 WEEK);
Reference