MySQL: Select with first and last day of previous month - mysql

Using PhpMyadmin, I have this sentence working:
SELECT id_order as Ref FROM t_orders WHERE DATE(invoice_date) = CURDATE()
Now I want to reemplace "current date" (CURDATE) for the first day of previous month in advance.
The answer of Ankit Bajpai solved my problem (thank you):
SELECT id_order as Ref FROM t_orders WHERE DATE(invoice_date) >= concat(date_format(LAST_DAY(now() - interval 1 month),'%Y-%m-'),'01');

in MYSQL you can try the below
First day of Previous Month
select last_day(curdate() - interval 2 month) + interval 1 day
Last day of Previous Month
select last_day(curdate() - interval 1 month)
First day of Current Month
select last_day(curdate() - interval 1 month) + interval 1 day
Last day of Current Month
select last_day(curdate())

Try following query:-
SELECT id_order as Ref
FROM t_orders
WHERE DATE(invoice_date) >= concat(date_format(LAST_DAY(now() - interval 1 month),'%Y-%m-'),'01');

For MS SQL Server:
DECLARE #firstDayOfLastMonth DATETIME = DATEADD(MONTH, -1, DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE()), 0))
DECLARE #lastDayOfLastMonth DATETIME = DATEADD(DAY, -1, DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE()), 0))
SELECT #firstDayOfLastMonth;
SELECT #lastDayOfLastMonth;

After reading closely... you want the entire month, of the previous month. You can do this:
SELECT id_order as Ref FROM t_orders
WHERE
DATE(invoice_date) >= DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE())-1, 0)
AND
DATE(invoice_date) <= DATEADD(month, DATEDIFF(MONTH, 0, GETDATE()), -1)
OR
SELECT id_order as Ref FROM t_orders
WHERE
MONTH(DATE(invoice_date)) = MONTH(DATEADD(MONTH,-1,GETDATE()))

Related

How to compare two dates in MySql exluding the weekends(SAT,SUN)

I want to find the difference between two dates(dateStart, dateEnd) only for weekdays that are Mon - Fri in MySql query.
Here is my query which compares two dates and gives result if a week or more has passed:
SELECT * FROM TABLE_NAME
WHERE status = 'Updated'
AND
DATE_ADD(dateModified, INTERVAL 1 WEEK) >= NOW();
SELECT *
FROM TABLE_NAME
WHERE status = 'Updated'
AND DATE_FORMAT(dateModified, '%w') IN (0, 6)
AND DATE_ADD(dateModified, INTERVAL 1 WEEK) >= NOW();
Please refer to
Official MySQL documentation for more info.
Create a Function as follows:
CREATE FUNCTION TOTAL_WEEKDAYS(date1 DATE, date2 DATE)
RETURNS INT
RETURN ABS(DATEDIFF(date2, date1)) + 1
- ABS(DATEDIFF(ADDDATE(date2, INTERVAL 1 - DAYOFWEEK(date2) DAY),
ADDDATE(date1, INTERVAL 1 - DAYOFWEEK(date1) DAY))) / 7 * 2
- (DAYOFWEEK(IF(date1 < date2, date1, date2)) = 1)
- (DAYOFWEEK(IF(date1 > date2, date1, date2)) = 7);
Then query like this:
SELECT * FROM TABLE_NAME WHERE status = 'Updated'
AND
TOTAL_WEEKDAYS(dateModified, NOW()) >=7;
Works like a charm!

Year-Over-Year Data for last week

I am currently writing a query that will give me last weeks data (lets assume "SALES") and last years data for the same week. This is what I have to get last weeks data and it works fine:
Set DATEFIRST 1
Select DATEPArt(dd, DateAdded) AS 'Day of the Month',
count(*)AS 'Number of Users'
from TABLE1
Where DateAdded >= dateadd(day, -(datepart(dw, getdate()) + 6), CONVERT(date,getdate()))
AND DateAdded < dateadd(day, 1-datepart(dw, getdate()), CONVERT(date,getdate()))
Group by DATEPArt(dd, DateAdded)
Order by 'Day of the Month'
Now I want to add another column that will give me last years data from the same week. This is what I was thinking:
Set DATEFIRST 1
Select DATEPArt(dd, DateAdded) AS 'Day of the Month',
count(*)AS 'Number of Users'
from TABLE1
Where DateAdded >= DATEADD(yy,DATEDIFF(yy,0,GETDATE())-1,0)
AND DateAdded < DATEADD(yy,DATEDIFF(yy,0,GETDATE())+1,0)
AND DateAdded >= dateadd(day, -(datepart(dw, getdate()) + 6), CONVERT(date,getdate()))
AND DateAdded < dateadd(day, 1-datepart(dw, getdate()), CONVERT(date,getdate()))
Group by DATEPArt(dd, DateAdded), DateAdded
Order by 'Day of the Month'
Problem is that I am still getting last weeks numbers (this year, I need it to be last year). This leads me to believe the error has to be here somewhere:
DateAdded >= DATEADD(yy,DATEDIFF(yy,0,GETDATE())-1,0)
AND DateAdded < DATEADD(yy,DATEDIFF(yy,0,GETDATE())+1,0)
I appreciate everyone's help!!
You are looking for an OR condition
WHERE (DateAdded >= DATEADD(yy,DATEDIFF(yy,0,GETDATE())-1,0)
AND DateAdded < DATEADD(yy,DATEDIFF(yy,0,GETDATE())+1,0))
OR (DateAdded >= dateadd(day, -(datepart(dw, getdate()) + 6), CONVERT(date,getdate()))
AND DateAdded < dateadd(day, 1-datepart(dw, getdate()), CONVERT(date,getdate())))

Grouping COUNT by Time in MySql

I have a simple query that give me the count of application types; it looks something like this:
SELECT Application_Type, COUNT(*) FROM Loan_Applications GROUP BY Application_Type;
It returns something like this:
Home 3
Car 21
Commercial 16
There is a field in the database called Submission_Date (Of type Date)
How can I query and break up this data by week?
Type This week Last week 2 weeks ago
Home 1 1 1
Car 9 6 6
Commercial 10 0 3
You can try something like:
SELECT
Application_Type,
SUM(IF(Submission_Date BETWEEN CURRENT_DATE AND CURRENT_DATE - INTERVAL 1 WEEK, 1, 0)) AS 'This week',
SUM(IF(Submission_Date BETWEEN CURRENT_DATE- INTERVAL 1 WEEK AND CURRENT_DATE - INTERVAL 2 WEEK, 1, 0)) AS 'Last week',
SUM(IF(Submission_Date BETWEEN CURRENT_DATE- INTERVAL 2 WEEK AND CURRENT_DATE - INTERVAL 3 WEEK, 1, 0)) AS '2 weeks ago',
FROM Loan_Applications
GROUP BY Application_Type
;
Or:
SET #date1w = CURRENT_DATE - INTERVAL 1 WEEK;
SET #date2w = CURRENT_DATE - INTERVAL 2 WEEK;
SET #date3w = CURRENT_DATE - INTERVAL 3 WEEK;
SELECT
Application_Type,
SUM(IF(Submission_Date BETWEEN CURRENT_DATE AND #date1w, 1, 0)) AS 'This week',
SUM(IF(Submission_Date BETWEEN #date1w AND #date2w, 1, 0)) AS 'Last week',
SUM(IF(Submission_Date BETWEEN #date2w AND #date3w, 1, 0)) AS '2 weeks ago',
FROM Loan_Applications
GROUP BY Application_Type
;
You can make a SUMIF type of calculation. The following sums the number of rows where the submission date is within the last week.
SUM(CASE WHEN submission_date >= CURDATE() - 7 THEN 1 ELSE 0 END)
You could then repeat this for different ranges, to get any "bands" that you desire.
Try
SELECT
Application_Type,
SUM(WEEKOFYEAR(Submission_Date) = WEEKOFYEAR(NOW())) AS `This week`,
SUM(WEEKOFYEAR(Submission_Date) = WEEKOFYEAR(DATE_ADD(NOW(),INTERVAL -1 WEEK))) AS `Last week`,
SUM(WEEKOFYEAR(Submission_Date) = WEEKOFYEAR(DATE_ADD(NOW(),INTERVAL -2 WEEK))) AS `2 weeks ago`
FROM Loan_Applications GROUP BY Application_Type;
;
it is based on the fact that SUM of a boolean expression in the group by will count the cases when the expression is true

Retrieving Data from database on quaterly basis condition But it should be based on current year data only

I had tried this code:
Its works also fine,but the issue is, if current month is feb and fire this query then it considers past 3 months from now and hence starts from past year i.e 2012 nov or dec say i want only current year data,if it is feb now and i fire this query then it should only show jan and feb records.
SELECT CROEmailId,
(
SELECT COUNT(LeadId)
FROM LeadStatus
WHERE DATE(`LeadTime`)> DATE_SUB(now(),
INTERVAL 3 MONTH
)
AND Generated=1 and AssignedTo=a.CROEmailId)
AS 'NEW LEAD',(
SELECT COUNT(LeadId)
FROM LeadHistory
WHERE DATE(UpdatedAt)> DATE_SUB(now(),
INTERVAL 3 MONTH
) AND AssignedTo=a.CROEmailId)
AS 'Lead Updated',
(
SELECT SUM(TotalEmails)
FROM MailJobs
WHERE DATE(CompletedAt)> DATE_SUB(now(),
INTERVAL 3 MONTH
)
AND MailFrom=a.CROEmailId)
AS 'Email Uploaded',
(
SELECT SUM(TotalSent)
FROM MailJobs
WHERE DATE(CompletedAt)> DATE_SUB(now(),
INTERVAL 3 MONTH)
AND MailFrom=a.CROEmailId
)
AS 'Email Sent',
(
SELECT SUM(NetTotal)
FROM Invoice
WHERE Status='PAID'
AND DATE(CreatedAt)> DATE_SUB(now(), INTERVAL 3 MONTH)
AND CROEmailId=a.CROEmailId)
AS 'Payment Today' FROM CustomersManager a;
Try change
DATE_SUB(now(), INTERVAL 3 MONTH)
to
IF(MONTH(CURDATE()) < 4, DATE_FORMAT(CURDATE(), '%Y-01-01'), CURDATE() - INTERVAL 3 MONTH)
in all subqueries.
SELECT CROEmailId,
(SELECT COUNT(LeadId)
FROM LeadStatus
WHERE DATE(`LeadTime`)> IF(MONTH(CURDATE()) < 4, DATE_FORMAT(CURDATE(), '%Y-01-01'), CURDATE() - INTERVAL 3 MONTH)
AND Generated=1
AND AssignedTo=a.CROEmailId) AS 'NEW LEAD',
(SELECT COUNT(LeadId)
FROM LeadHistory
WHERE DATE(UpdatedAt)> IF(MONTH(CURDATE()) < 4, DATE_FORMAT(CURDATE(), '%Y-01-01'), CURDATE() - INTERVAL 3 MONTH)
AND AssignedTo=a.CROEmailId) AS 'Lead Updated',
(SELECT SUM(TotalEmails)
from MailJobs
WHERE DATE(CompletedAt)> IF(MONTH(CURDATE()) < 4, DATE_FORMAT(CURDATE(), '%Y-01-01'), CURDATE() - INTERVAL 3 MONTH)
AND MailFrom=a.CROEmailId) AS 'Email Uploaded',
(SELECT SUM(TotalSent)
FROM MailJobs
WHERE DATE(CompletedAt)> IF(MONTH(CURDATE()) < 4, DATE_FORMAT(CURDATE(), '%Y-01-01'), CURDATE() - INTERVAL 3 MONTH)
AND MailFrom=a.CROEmailId) AS 'Email Sent',
(SELECT SUM(NetTotal)
FROM Invoice
WHERE Status='PAID'
AND DATE(CreatedAt)> IF(MONTH(CURDATE()) < 4, DATE_FORMAT(CURDATE(), '%Y-01-01'), CURDATE() - INTERVAL 3 MONTH)
AND CROEmailId=a.CROEmailId) AS 'Payment Today'
FROM CustomersManager a;
use this in your query to find record filter by year
YEAR( '20013-12-12' )
example,
SELECT * FROM TABLE WHERE YEAR(DATE_FIELD) = 2013

Changing start-date in MySQL for week

I found the following code to help in creating a weekly report based on a start date of Friday. The instructions say to replace ".$startWeekDay." with a 4. When I put '".$startDay."' as '2013-01-30', I get errors.
Also I get a report by day rather than week as I desire.
SELECT SUM(cost) AS total,
CONCAT(IF(date - INTERVAL 6 day < '".$startDay."',
'".$startDay."',
IF(WEEKDAY(date - INTERVAL 6 DAY) = ".$startWeekDay.",
date - INTERVAL 6 DAY,
date - INTERVAL ((WEEKDAY(date) - ".$startWeekDay.")) DAY)),
' - ', date) AS week,
IF((WEEKDAY(date) - ".$startWeekDay.") >= 0,
TO_DAYS(date) - (WEEKDAY(date) - ".$startWeekDay."),
TO_DAYS(date) - (7 - (".$startWeekDay." - WEEKDAY(date)))) AS sortDay
FROM daily_expense
WHERE date BETWEEN '".$startDay."' AND '".$endDay."'
GROUP BY sortDay;
The following code is what I am using
SELECT count(DISTINCT (
UserID)
) AS total, CONCAT(IF(date(LastModified) - INTERVAL 6 day < date(LastModified),
date(LastModified),
IF(WEEKDAY(date(LastModified) - INTERVAL 6 DAY) = 4,
date(LastModified) - INTERVAL 6 DAY,
date(LastModified) - INTERVAL ((WEEKDAY(date(LastModified)) - 4)) DAY)),
' - ', date(LastModified)) AS week
FROM `Purchase`
WHERE `OfferingID` =87
AND `Status`
IN ( 1, 4 )
GROUP BY week
The output I get is
total week
3 2013-01-30 - 2013-01-30
1 2013-01-31 - 2013-01-31
I'm not sure exactly how you want to display your week, the sql above is attempting to display date ranges. If this isn't a requirement, your query could be very simple, you can just offset your time by two days (since friday is two days away from the natural star of the week) and use the week function to get the week number.
The query would look like this:
select count(distinct (UserID)) as total
, year( LastModified + interval 2 day ) as year
, week( LastModified + interval 2 day ) as week_number
FROM `Purchase`
WHERE `OfferingID` =87
AND `Status`
IN ( 1, 4 )
group by year, week_number;