Counting days by non standard days end - mysql

I am trying to count events that happen in a day, which in itself is easy:
SELECT date(time),COUNT(DISTINCT comment)
FROM data
GROUP BY date(time)
But I need a day end to be set at 4pm. So all comments before 4pm is day N, and news after 4pm are day N+1. This isnt a global thing, so I'd rather not change time zone of entire program and etc. Maybe I can somehow apply timezone to this query or pad time?

SELECT
DATE_ADD(date(time),
INTERVAL case when time(time)>='16:00:00' then 1 else 0 end DAY) as day,
COUNT(DISTINCT comment)
FROM data
GROUP BY day

Have you tried this:
SELECT date(time + INTERVAL 8 HOUR) as day, COUNT(DISTINCT comment)
FROM data
GROUP BY day
You want your days to end at 4PM, or 8 hours early so, we add 8 hours to time, forcing the date to roll over at 4PM.

Related

How to get the count of specific days from week between a date range in mysql?

I have a table "task_table" containing columns-
Task_id, Start_date, End_date
And I have one more "configuration" table which has the records that tell which days of the week are working days.
This table has two columns -
week_day, isHoliday
and this table contains seven records as week_days are the Monday,Tuesday.....Sunday , and each record has an entry as 1 or 0. If a day is a holiday in any organization then there will be 0 against that day. Like if an organisation has holidays on Wednesday and Friday every week then there will be 0 against Wednesday and Friday only.
Now I want to make a SQL query to get the Task_id, Start_date, End_date, and the count of total days consumed on each task. (These days are the days between task start_date and end_date excluding the holiday days as configured in "configuration" table.)
I don't have time to fully answer this question now, but what I would do is:
Get the date as at the start of the Start_date week, and the date as at the end of the End_date week (you can get this by date_adding an amount of days according to the day of the week.
Then you want to date diff them, divide by seven, multiply by two, and remove any that you would have added (e.g. if the start date was Thursday then you'll need to remove one from the result, as you will have counted one for the Wednesday immediately prior.
I'll write the code out tomorrow (it's late here - something like 14 hours from now or so.) if noone else has suggested a better answer.
Edit: Right, didn't properly read the question, but the tactic still applies with a little fiddling. Speaking of which, here is the fiddle of my solution.
It boils down to the following code:
set #holidaysPerWeek = (select sum(isHoliday) from configuration);
select
Task_id,
((dateDiff(
DATE_ADD(End_Date, INTERVAL 7 - DayOfWeek(End_Date) DAY),
DATE_ADD(Start_Date, INTERVAL -DayOfWeek(Start_Date) + 1 Day)) + 1) / 7)
* #holidaysPerWeek
- (select sum(isHoliday) from configuration where week_day > DayOfWeek(End_Date))
- (select sum(isHoliday) from configuration where week_day < DayOfWeek(Start_Date)),
DayOfWeek(End_Date)
from task_table
This does exactly what I was saying before, but with a variable number of "weekends" spread throughout the week, by first selecting the number of holidays for if the full weeks were covered, then removing holidays that were before or after the start and end dates respectively.

MySql date_add() query improvement

I am running a query that gets today's activity as at now() and compares it to activity at the same time for the past 5 days.
select count(*) ,date(timestamp) date , now() now
from activitylog
where timestamp>date_add(now(), INTERVAL -5 DAY) and
hour(timestamp) <=hour(now())
group by date(timestamp)
order by date(timestamp) desc;
Is there a way of doing it more efficiently than the above way?
As written, the query will return the day's activity up to the current hour for the current day and the previous 4 days, plus the current hour's activity only for five days ago - to make it include the whole day to the current hour for the fifth day, change the where clause to:
where timestamp>date(date_add(now(), INTERVAL -5 DAY)) and
hour(timestamp) <=hour(now())
Apart from this, the only issue I can think of is to check that there is an index on the timestamp column. Otherwise, it appears to be in its optimum form.

Pick records since last particular day of week

I want to pick and SUM values since last wednesday until NOW() in mysql. How can I do that?
Sorry for incomplete question, by the last Wednesday I did not mean to hard-code the date, rather I want my program to run that query, so it cannot hard-code--- Needs a flexible solution. Please help...
select date_sub(now(), interval dayofweek(date_sub(now(), interval 4 day)) day);
This works on any day of the week and always returns the Wednesday which has most recently passed. On a Wednesday itself, it returns the previous Wednesday. The next day, it returns yesterday
Genesis is right (He's very right, use his suggestion), but as an intellectual exercise: This is the best pure MySQL I could think of:
SELECT * FROM TABLE
WHERE
DATE_COLUMN > DATE_SUB( NOW(), INTERVAL DAYOFWEEK(NOW()) + 3 DAY);
NOW - DAYOFWEEK => this past Saturday. Weds. is three days before that.
SELECT SUM(value) FROM table WHERE date > '2011-07-20'
You should calculate your date from your programming language (fastest solution)

How do I select two weeks ago in MYSQL?

I have a report that is driven by a sql query that looks like this:
SELECT batch_log.userid,
batches.operation_id,
SUM(TIME_TO_SEC(ramses.batch_log.time_elapsed)),
SUM(ramses.tasks.estimated_nonrecurring + ramses.tasks.estimated_recurring),
DATE(start_time)
FROM batch_log
JOIN batches ON batch_log.batch_id=batches.id
JOIN ramses.tasks ON ramses.batch_log.batch_id=ramses.tasks.batch_id
JOIN protocase.tblusers on ramses.batch_log.userid = protocase.tblusers.userid
WHERE DATE(ramses.batch_log.start_time) > "2011-02-01"
AND ramses.batch_log.time_elapsed > "00:03:00"
AND DATE(ramses.batch_log.start_time) < now()
AND protocase.tblusers.active = 1
AND protocase.tblusers.userid NOT in ("ksnow","smanning", "dstapleton")
GROUP BY userid, batches.operation_id, date(start_time)
ORDER BY start_time, userid ASC
Since this is to be compared with the time from the current payperiod it causes an error.
Our pay periods start on a Sunday, the first pay period was 2011-02-01 and our last pay period started the 4th of this month. How do I put that into my where statement to strip the most recent pay period out of the query?
EDIT: So now I'm using date_sub(now(), INTERVAL 2 WEEK) but I really need a particular day of the week(SUNDAY) since it is wednesday it's chopping it off at wednesday.
You want to use DATE_SUB, and as an example.
Specifically:
select DATE_SUB(curdate(), INTERVAL 2 WEEK)
gets you two weeks ago. Insert the DATE_SUB ... part into your sql and you're good to go.
Edit per your comment:
Check out DAYOFWEEK:
and you can do something along the lines of:
DATE_SUB(DATE_SUB(curdate(), INTERVAL 2 WEEK), INTERVAL 2 + DAYOFWEEK(curdate()) DAY)
(I don't have a MySql instance to test it on .. but essentially subtract the number of days after Monday.)
Question isn't quite clear, especially after the edit - it isn't clear now is the "pay period" two weeks long or do you want just last two weeks back from last sunday? I assume that the period is two weeks... then you first need to know how many days the latest period (which you want to ignore, as it isn't over yet) has been going on. To get that number of days you can use expression like
DATEDIFF(today, FirstPeriod) % 14
where FirstPeriod is 2011-02-01. And now you strip that number of days from the current date in the query using date_sub(). The exact expression depends on how the period is defined but you should get the idea...

Trying to select the number of mysql rows inserted yesterday

I can normally do this but it appears my brain is not functioning well right now and I'm missing something.
Every day via a cron job that is run at 1am, I want to get a count of rows that were inserted yesterday, and the date.
ie
SELECT DATE(added) as date, COUNT(*) FROM bookings WHERE added = DATE_SUB(NOW(), INTERVAL 1 DAY) GROUP BY date
'added' contains a timestamp ie '2011-04-18 12:31:31'
What am I getting wrong here? I know there are many rows added yesterday but my query is returning 0 results and no mysql_errors :(
Any ideas?
Please try
SELECT DATE(added) as yesterday, COUNT(*) FROM bookings WHERE DATE(added) = DATE(DATE_SUB(NOW(), INTERVAL 1 DAY)) GROUP BY yesterday
or perhaps
SELECT DATE(added) as yesterday, COUNT(*) FROM bookings WHERE DATE(added) = DATE_SUB(CURDATE(), INTERVAL 1 DAY) GROUP BY yesterday
Updated
Corrected the WHERE part.
well whatever NOW() is will return the time portion and unless they were added at exactly that time the day before they wont be counted.
So either use BETWEEN and specify time range, or format the date in your query to only match on the day month year components and not time
WHERE added = does only match exact NOW() - 1 DAY, you should select by a range instead.