SQL Birthday Query - mysql

Hey I'm a bit of a beginner with SQL but i'm trying to write a query to pull out all records if its someones birthday within the next 7 days and have looked at other threads with answers but I'm having trouble adapting them to my setup.
SELECT *
FROM `QG04c`
WHERE month( `dob` ) = month( now( ) )
AND day( `dob` )
BETWEEN day( now( ) )
AND day( now( ) ) +7
AND `Primary Unit?` =1
At the moment this pulls out everyone whose birthday is within 7 days but I don't think it will cope with end of the month scenarios and end of year etc.

Assuming this is MySQL, you can use the DAYOFYEAR function to get the day of the year a birthday occurs. The simple scenario is everything from 1st Jan - 25th December, where 7 days ahead is in the same year. For this you can use:
SELECT *
FROM `QG04c`
WHERE DAYOFYEAR(DOB) - DAYOFYEAR(CURDATE()) BETWEEN 0 AND 7;
However when today is between 25th Dec - 31st Dec you need to account for the birthday being between 1st and 6th Jan. To do this you need:
SELECT *
FROM `QG04c`
WHERE DAYOFYEAR(CURDATE() + INTERVAL 7 DAY) < 7
AND DAYOFYEAR(DOB) < DAYOFYEAR(CURDATE() + INTERVAL 7 DAY);
Then it is just a matter of combining the two cases:
SELECT *
FROM `QG04c`
WHERE DAYOFYEAR(DOB) - DAYOFYEAR(CURDATE()) BETWEEN 0 AND 7
OR ( DAYOFYEAR(CURDATE() + INTERVAL 7 DAY) < 7
AND DAYOFYEAR(DOB) < DAYOFYEAR(CURDATE() + INTERVAL 7 DAY)
);
Examples on SQL Fiddle

select * from tablename WHERE [ColumnName] BETWEEN DATEADD(DAY, +7, #YourDate) AND #YourDate and Primary Unit = 1 (If you have and condition put add here)
Thanks .

Should be easy if you don't decompose the day?
WHERE `dob` BETWEEN now() AND now() +7

Related

MYSQL: Getting all results from last week starting Monday)

CREATE TABLE `sport_data` (
`id` int(255) NOT NULL,
`date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`sport` varchar(255) NOT NULL,
`musclePlan` varchar(255) NOT NULL,
`sport_time` varchar(255) NOT NULL,
`kcal` varchar(255) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
How can i get all data from this table from the last week (from Monday to Sunday)?
I have tried:
WHERE date >= curdate() - INTERVAL DAYOFWEEK(curdate())+5 DAY AND date < curdate() - INTERVAL DAYOFWEEK(curdate())-2 DAY
I don't know if this is correct that way?
Thanks in advance.
The >= and < pattern is what we usually use. That part looks right.
I think the question is about the expressions that returning the range start and end values.
I suggest that we test those expressions for a variety of date values, not just CURDATE(). We can use a value in place of CURDATE(), and check the results, and do that for a series of date values.
Conveniently, those expressions will evaluate the same in a SELECT list as they do in a WHERE clause. So we can run a SELECT statement, and check the results.
For example:
SELECT t.dt AS dt
, t.dt - INTERVAL DAYOFWEEK(t.dt)+5 DAY AS _ge
, t.dt - INTERVAL DAYOFWEEK(t.dt)-2 DAY AS _lt
FROM (
SELECT CURDATE() + INTERVAL 0 DAY AS dt
UNION ALL SELECT CURDATE() + INTERVAL -1 DAY
UNION ALL SELECT CURDATE() + INTERVAL -2 DAY
UNION ALL SELECT CURDATE() + INTERVAL -3 DAY
UNION ALL SELECT CURDATE() + INTERVAL -4 DAY
UNION ALL SELECT CURDATE() + INTERVAL -5 DAY
UNION ALL SELECT CURDATE() + INTERVAL -6 DAY
UNION ALL SELECT CURDATE() + INTERVAL -7 DAY
UNION ALL SELECT CURDATE() + INTERVAL -8 DAY
UNION ALL SELECT CURDATE() + INTERVAL -9 DAY
UNION ALL SELECT CURDATE() + INTERVAL -10 DAY
) t
If the expressions are returning the values we expect, in accordance with the specification, for each possible date value, then the expressions are right.
If the expressions are returning values that don't meet the spec, then we need to make adjustments. Note that an expression that "works" on a Wednesday date might not "work" on a Sunday date.)
DEMO: Showing 3 approaches and why current doesn't work.
If we assume by "last week" you mean the last full week Monday - Sunday of a week prior to the day you're presently on...
So if today was 20180422, you'd want 20180409-20180415
SELECT *
FROM SO50026532_sport_data
CROSS JOIN (SELECT #Today:=curdate()) z
WHERE date >= #today - interval (6 + case when dayofweek(#today)=1 then 7 else dayofWeek(#today)-1 end) day
and date <=#today - interval (case when dayofweek(#today)=1 then 7 else dayofWeek(#today)-1 end) day;
Or if your a fan of the >= and < then
SELECT *
FROM SO50026532_sport_data
CROSS JOIN (SELECT #Today:=curdate()) z
WHERE date >= #today - interval (6 + case when dayofweek(#today)=1 then 7 else dayofWeek(#today)-1 end) day
and date <#today - interval (case when dayofweek(#today)=1 then 7 else dayofWeek(#today)-1 end-1) day;
in the 2nd example we had to subtract by 1 since dayofweek isn't a 0 based. Of course I could have just date shifted everything down 2 and set sunday to 6... then I wouldn't' need to subtract by 1. and then we'd be adding 7 instead of 6 on the 1st part of the where. (demo has these 3 and your initial example showing what happens on 4/22.
Dayofweek starts on Sunday being 1. So I use a case statement to shift 1 to 7 and and all the others down 1 giving us Monday = 1 and sunday = 7
The cross join to derived table z was so I could control the curdate() easier and test. You could replace the variable with curdate() if you want and eliminate the cross join and derived table.
The first where clause subtracts 6 days (1 week and then the # of days from current date back to monday. This ensures we always start 1 week back from current date and on a monday. then we only get dates to the Sunday of that week.

Sql Query for getting last 8 days data

For getting last 8 days details I am using this condition in my query.
bill_date <= ( CURDATE( ) - INTERVAL 8 DAY )
But I am not getting the proper result.Last 8 days means 25th april - 2nd may. What is wrong in my condition and is there any another way to do the same?
Try this method
bill_date >=DATE_ADD(CURENT_DATE(),INTERVAL -8 DAY ) AND bill_date<CURRENT_DATE()
Try this
bill_date >= (sysdate - 8)
Try this to get last 8 days details
bill_date >= ( CURDATE( ) - INTERVAL 8 DAY ) --After 25th Apr
or (if you have records in future date, then use this query)
bill_date >= ( CURDATE( ) - INTERVAL 8 DAY ) AND bill_date <= CURRENT_DATE() -- From 25th Apr - 2nd May
it should be bill_date >= ( instead of <= ), because you want the result after the 25th Apr. So your condition should be bill_date >= 25th Apr.
Try this
bill_date between CURDATE() - INTERVAL 8 DAY and curdate() + interval 1 day - interval 1 second

How to get last 2 or 3 months data in MySQL?

I m trying to get last 2 and 3 months data.
e.g Last 2 months data means Dec 2014 To Jan 2015 and 3 months means Nov 2014 TO Jan 2015
I tried
SELECT * FROM d_jobs WHERE `job_date` >= DATE_ADD( NOW( ) , INTERVAL -1 MONTH )
Here Its Count last 30 days data only .
So Which is the best way to perform this ?
Try this:
SELECT * FROM d_jobs WHERE `job_date` >= last_day(now()) + interval 1 day - interval 3 month;
Try with this query hope you will overcome your problem i think
select * from d_jobs where job_date < Now() and job_date > DATE_ADD(Now(), INTERVAL- 3 MONTH);
select * from d_jobs where job_date BETWEEN SUBDATE(CURDATE(), INTERVAL 3 MONTH) AND NOW();
select * from d_jobs WHERE job_date BETWEEN STR_TO_DATE('2012-09-01', '%Y-%m-%d') AND NOW();
Get left 7 chars of current date in ISO format (i.e. '2015-01'). Then add "-01" for 1st day of month (result is "2015-01-01"). Then use INTERVAL ... MONTH to get last months.

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;

How do I select between the 1st day of the current month and current day in MySQL?

I need to select data from MySQL database between the 1st day of the current month and current day.
select*from table_name
where date between "1st day of current month" and "current day"
Can someone provide working example of this query?
select * from table_name
where (date between DATE_ADD(LAST_DAY(DATE_SUB(CURDATE(), interval 30 day), interval 1 day) AND CURDATE() )
Or better :
select * from table_name
where (date between DATE_FORMAT(NOW() ,'%Y-%m-01') AND NOW() )
I was looking for a similar query where I needed to use the first day of a month in my query.
The last_day function didn't work for me but DAYOFMONTH came in handy.
So if anyone is looking for the same issue, the following code returns the date for first day of the current month.
SELECT DATE_SUB(CURRENT_DATE, INTERVAL DAYOFMONTH(CURRENT_DATE)-1 DAY);
Comparing a date column with the first day of the month :
select * from table_name where date between
DATE_SUB(CURRENT_DATE, INTERVAL DAYOFMONTH(CURRENT_DATE)-1 DAY) and CURRENT_DATE
select * from table_name
where `date` between curdate() - dayofmonth(curdate()) + 1
and curdate()
SQLFiddle example
I have used the following query. It has worked great for me in the past.
select date(now()) - interval day(now()) day + interval 1 day
try this :
SET #StartDate = DATE_SUB(DATE(NOW()),INTERVAL (DAY(NOW())-1) DAY);
SET #EndDate = ADDDATE(CURDATE(),1);
select * from table where (date >= #StartDate and date < #EndDate);
Complete solution for mysql current month and current year, which makes use of indexing properly as well :)
-- Current month
SELECT id, timestampfield
FROM table1
WHERE timestampfield >= DATE_SUB(CURRENT_DATE, INTERVAL DAYOFMONTH(CURRENT_DATE)-1 DAY)
AND timestampfield <= LAST_DAY(CURRENT_DATE);
-- Current year
SELECT id, timestampfield
FROM table1
WHERE timestampfield >= DATE_SUB(CURRENT_DATE, INTERVAL DAYOFYEAR(CURRENT_DATE)-1 DAY)
AND timestampfield <= LAST_DAY(CURRENT_DATE);
select * from table
where date between
(date_add (CURRENT_DATE, INTERVAL(1 - DAYOFMonth(CURRENT_DATE)) day)) and current_date;
select * from <table>
where <dateValue> between last_day(curdate() - interval 1 month + interval 1 day)
and curdate();
I found myself here after needing this same query for some Business Intelligence Queries I'm running on an e-commerce store. I wanted to add my solution as it may be helpful to others.
set #firstOfLastLastMonth = DATE_SUB(LAST_DAY(DATE_ADD(NOW(), INTERVAL -2 MONTH)),INTERVAL DAY(LAST_DAY(DATE_ADD(NOW(), INTERVAL -2 MONTH)))-1 DAY);
set #lastOfLastLastMonth = LAST_DAY(DATE_ADD(NOW(), INTERVAL -2 MONTH));
set #firstOfLastMonth = DATE_SUB(LAST_DAY(DATE_ADD(NOW(), INTERVAL -1 MONTH)),INTERVAL DAY(LAST_DAY(DATE_ADD(NOW(), INTERVAL -1 MONTH)))-1 DAY);
set #lastOfLastMonth = LAST_DAY(DATE_ADD(NOW(), INTERVAL -1 MONTH));
set #firstOfMonth = DATE_ADD(#lastOfLastMonth, INTERVAL 1 DAY);
set #today = CURRENT_DATE;
Today is 2019-10-08 so the output looks like
#firstOfLastLastMonth = '2019-08-01'
#lastOfLastLastMonth = '2019-08-31'
#firstOfLastMonth = '2019-09-01'
#lastOfLastMonth = '2019-09-30'
#firstOfMonth = '2019-10-01'
#today = '2019-10-08'
A less orthodox approach might be
SELECT * FROM table_name
WHERE LEFT(table_name.date, 7) = LEFT(CURDATE(), 7)
AND table_name.date <= CURDATE();
as a date being between the first of a month and now is equivalent to a date being in this month, and before now. I do feel that this is a bit easier on the eyes than some other approaches, though.
SELECT date_sub(current_date(),interval dayofmonth(current_date())-1 day) as first_day_of_month;
I had some what similar requirement - to find first day of the month but based on year end month selected by user in their profile page.
Problem statement - find all the txns done by the user in his/her financial year. Financial year is determined using year end month value where month can be any valid month - 1 for Jan, 2 for Feb, 3 for Mar,....12 for Dec.
For some clients financial year ends on March and some observe it on December.
Scenarios - (Today is `08 Aug, 2018`)
1. If `financial year` ends on `July` then query should return `01 Aug 2018`.
2. If `financial year` ends on `December` then query should return `01 January 2018`.
3. If `financial year` ends on `March` then query should return `01 April 2018`.
4. If `financial year` ends on `September` then query should return `01 October 2017`.
And, finally below is the query. -
select #date := (case when ? >= month(now())
then date_format((subdate(subdate(now(), interval (12 - ? + month(now()) - 1) month), interval day(now()) - 2 day)) ,'%Y-%m-01')
else date_format((subdate(now(), interval month(now()) - ? - 1 month)), '%Y-%m-01') end)
where ? is year end month (values from 1 to 12).
The key here is to get the first day of the month. For that, there are several options. In terms of performance, our tests show that there isn't a significant difference between them - we wrote a whole blog article on the topic. Our findings show that what really matters is whether you need the result to be VARCHAR, DATETIME, or DATE.
The fastest solution to the real problem of getting the first day of the month returns VARCHAR:
SELECT CONCAT(LEFT(CURRENT_DATE, 7), '-01') AS first_day_of_month;
The second fastest solution gives a DATETIME result - this runs about 3x slower than the previous:
SELECT TIMESTAMP(CONCAT(LEFT(CURRENT_DATE, 7), '-01')) AS first_day_of_month;
The slowest solutions return DATE objects. Don't believe me? Run this SQL Fiddle and see for yourself 😊
In your case, since you need to compare the value with other DATE values in your table, it doesn't really matter what methodology you use because MySQL will do the conversion implicitly even if your formula doesn't return a DATE object.
So really, take your pick. Which is most readable for you? I'd pick the first since it's the shortest and arguably the simplest:
SELECT * FROM table_name
WHERE date BETWEEN CONCAT(LEFT(CURRENT_DATE, 7), '-01') AND CURDATE;
SELECT * FROM table_name
WHERE date BETWEEN DATE(CONCAT(LEFT(CURRENT_DATE, 7), '-01')) AND CURDATE;
SELECT * FROM table_name
WHERE date BETWEEN (LAST_DAY(CURRENT_DATE) + INTERVAL 1 DAY - INTERVAL 1 MONTH) AND CURDATE;
SELECT * FROM table_name
WHERE date BETWEEN (DATE(CURRENT_DATE) - INTERVAL (DAYOFMONTH(CURRENT_DATE) - 1) DAY) AND CURDATE;
SELECT * FROM table_name
WHERE date BETWEEN (DATE(CURRENT_DATE) - INTERVAL (DAYOFMONTH(CURRENT_DATE)) DAY + INTERVAL 1 DAY) AND CURDATE;
SELECT * FROM table_name
WHERE date BETWEEN DATE_FORMAT(CURRENT_DATE,'%Y-%m-01') AND CURDATE;
I used this one
select DATE_ADD(DATE_SUB(LAST_DAY(now()), INTERVAL 1 MONTH),INTERVAL 1 day) first_day
,LAST_DAY(now()) last_day, date(now()) today_day
All the responses here have been way too complex. You know that the first of the current month is the current date but with 01 as the date. You can just use YEAR() and MONTH() to build the month date by inputting the NOW() method.
Here's the solution:
select * from table_name
where date between CONCAT_WS('-', YEAR( NOW() ), MONTH( NOW() ), '01') and DATE( NOW() )
CONCAT_WS() joins a series of strings with a separator (a dash in this case).
So if today is 2020-08-28, YEAR( NOW() ) = '2020' and MONTH( NOW() ) = '08' and then you just need to append '01' at the end.
Voila!
Get first date and last date from month and year.
select LAST_DAY(CONCAT(year,'.',month,'.','01')) as registerDate from user;
select date_add(date_add(LAST_DAY(end_date),interval 1 DAY),interval -1 MONTH) AS closingDate from user;
SET #date:='2012-07-11';
SELECT date_add(date_add(LAST_DAY(#date),interval 1 DAY),
interval -1 MONTH) AS first_day