I have a field date_purchased and date_ordered which are datetime fields. Now I need to fetch the record if the product was purchased after order, and if the puchase was 2 days earlier or 7 days after order:
if(date_purchased>date_ordered)
{
if(date_purchased>(today-2) or date_puchased<(date_ordered+7))
}
Basically, how do I translate the above code to mysql where condition( nested and/or)?
Use DATE_SUB() and DATE_ADD() to add days to a datetime field. The two date comparisons are enclosed in () as a single component to the AND.
WHERE
date_purchased > date_ordered
AND (
date_purchased > DATE_SUB(NOW(), INTERVAL 2 DAY)
OR date_purchased < DATE_ADD(date_ordered, INTERVAL 7 DAY)
)
Note If these are DATETIME fields rather than DATE fields, you may want to strip off the time portion with DATE() so that the day comparisons start at the beginning of the day, rather than some 24 hour interval from the current time. This also means using CURDATE() instead of NOW() to get today's date rather than a timestamp.
WHERE
date_purchased > date_ordered
AND (
DATE(date_purchased) > DATE_SUB(CURDATE(), INTERVAL 2 DAY)
OR DATE(date_purchased) < DATE_ADD(DATE(date_ordered), INTERVAL 7 DAY)
)
Use the BETWEEN operator to select the interval.
WHERE d BETWEEN *date-2 AND *date+7
SELECT * FROM your_table
WHERE date_purchased > date_ordered
AND (DATE_DIFF(date_purchased, date_ordered) > 2
OR DATE_DIFF(date_purchased, date_ordered) < -7)
Related
I have table with timestamp in one column (MySQL 5.5). Is it possible to get number of records during last 1 day (last 86400 seconds) and number of records during last week (last 604800 seconds) in single query?
I know how to do it with 2 queries, but it would be nice to know if there is some neat solution to this.
timestamp > DATE_SUB(NOW(), INTERVAL 1 DAY)
timestamp > DATE_SUB(NOW(), INTERVAL 1 WEEK)
Quick and Dirty is just a Union then.
Select '1 Days', Count(*) as NumberOf from sometable
Where `timestamp` > DATE_SUB(NOW(), INTERVAL 1 DAY)
union
Select '7 Days', Count(*) as from sometable
Where `timestamp` > DATE_SUB(NOW(), INTERVAL 1 WEEK)
Gets painful and perhaps expensive if you have a lot of ranges though. f So you might want to look at DateDiff to calculate the interval once and then count that.
I am trying to select data from two periods (Last 30 days and Previous 30 days)
So two 30 day periods.
I have the last 30 day period down:
SELECT ProductID, ProductIDintarget,date_format(Date,'%m/%d/%Y'),SUM(Rev)
FROM datatable
WHERE Date BETWEEN CURDATE()-1 - INTERVAL 31 DAY AND CURDATE()
GROUP BY ProductIDintarget
That is working fine, but now I'm struggling to get the previous 30 day period.
I have tried changing the WHERE statement as:
WHERE Date BETWEEN CURDATE()-32 - INTERVAL 31 DAY AND CURDATE()-32
but no luck..
You can use DATE_ADD() or DATE_SUB() like this:
SELECT
ProductID,
ProductIDintarget,
DATE_FORMAT(Date,'%m/%d/%Y'),
SUM(Rev)
FROM datatable
WHERE `Date` < (DATE_ADD(CURDATE(), INTERVAL 1 MONTH))
AND `Date` > (DATE_SUB(CURDATE(), INTERVAL 2 MONTH))
GROUP BY
ProductID,
ProductIDintarget,
`Date`
Note:- You should backticks if you have keywords as column names.
Suppose I have a table with 3 columns: EMPLOYEE_ID, NUM_SALES, DATE. Simply this is the table of Employees indicating daily sales. For each row in the table, I try to compute this; average number of sales of that EMPLOYEE_ID in the last K days excluding this day.
How can I query this in MySQL? I try to group by with EMPLOYEE_ID and DATE but I cannot figure out how to find last K sales for each row.
To select an interval of days, you can use MySQL's DATE_SUB() function:
WHERE `date` >= DATE_SUB(NOW(), INTERVAL 3 DAY)
This will select all records that are from the past 3 days. However, to exclude "today" from that:
WHERE `date` BETWEEN
DATE_SUB(NOW(), INTERVAL 3 DAY)
AND DATE_SUB(NOW(), INTERVAL 1 DAY)
After that you should be able to GROUP BY the employee_id to get what you're after:
SELECT
employee_id, avg(num_sales) AS avg_num_sales
FROM
employee_table
WHERE `date` BETWEEN
DATE_SUB(NOW(), INTERVAL 3 DAY)
AND DATE_SUB(NOW(), INTERVAL 1 DAY)
GROUP BY
employee_id
You need to be able to select items from your table, let's call it dailysale, by date.
Here's what you do.
SELECT employee_id, AVG(num_sales) AS avg_sales
FROM dailysale
WHERE date >= CURDATE() - INTERVAL 3 DAY
AND date < CURDATE()
GROUP BY employee_id
This uses two WHERE clauses to winnow down the date range you're using. date >= CURDATE() - INTERVAL 3 DAY excludes all records before midnight three days ago, and date < CURDATE() excludes all records on or after midnight today.
You need to use CURDATE() rather than NOW() because, well, NOW() includes the date and the present time of day. date < NOW() will include today's sales, because your date column only records dates and not times.
If you want to list the employees in order of sales, you could add
ORDER BY AVG(num_sales) DESC, employee_id
to the query.
I have a table containing data about events and festivals with following columns recording their start and end dates.
Start_Date
End_Date
date format is in YYYY-MM-DD. I need to fetch event details with the following condition.
Need to fetch all events which start with a current month and there end dates can be anything say currentDate+next30days.
I am clear about end date concept. but not sure how I can fetch data whose start dates are in a current month.
For this, I need to compare current year and current month against the Start_Date column in my database.
Can anyone help me to point out as how I can do that?
select * from your_table
where year(Start_Date) = year(curdate())
and month(Start_Date) = month(curdate())
and end_date <= curdate() + interval 30 day
I don't like either of the other two answers, because they do not let the optimizer use an index on start_date. For that, the functions need to be on the current date side.
So, I would go for:
where start_date >= date_add(curdate(), interval 1 - day(curdate()) day) and
start_date < date_add(date_add(curdate(), interval 1 - day(curdate()) day), interval 1 month)
All the date functions are on curdate(), which does not affect the ability of MySQL to use an index in this case.
You can also include the condition on end_date:
where (start_date >= date_add(curdate(), interval 1 - day(curdate()) day) and
start_date < date_add(date_add(curdate(), interval 1 - day(curdate()) day), interval 1 month)
) and
end_date <= date_add(curdate(), interval 30 day)
This can still take advantage of an index.
DateTime functions are your friends:
SELECT
*
FROM
`event`
WHERE
(MONTH(NOW()) = MONTH(`Start_Date`))
AND
(`End_Date` <= (NOW() + INTERVAL 30 DAY))
AND
(YEAR(NOW()) = YEAR(`Start_Date`))
Comparing the year and month separately feels messy. I like to contain it in one line. I doubt it will make a noticeable difference in performance, so its purely personal preference.
select * from your_table
where LAST_DAY(Start_Date) = LAST_DAY(curdate())
and end_date <= curdate() + interval 30 day
So all I'm doing is using the last_day function to check the last day of the month of each date and then comparing this common denominator. You could also use
where DATE_FORMAT(Start_Date ,'%Y-%m-01') = DATE_FORMAT(curdate(),'%Y-%m-01')
I want to do SELECT count(*) FROM users where created_at within 3 days ago
Created_at is datetime column.
Use for a date three days ago:
WHERE t.date >= DATE_ADD(CURDATE(), INTERVAL -3 DAY);
Check the DATE_ADD documentation.
Or you can use:
WHERE t.date >= ( CURDATE() - INTERVAL 3 DAY )