Monthly Birthday SQL Query - sql

How would retrieve all customer's birthdays for a given month in SQL? What about MySQL?
I was thinking of using the following with SQL server.
select c.name
from cust c
where datename(m,c.birthdate) = datename(m,#suppliedDate)
order by c.name

don't forget the 29th February...
SELECT c.name
FROM cust c
WHERE (
MONTH(c.birthdate) = MONTH(#suppliedDate)
AND DAY(c.birthdate) = DAY(#suppliedDate)
) OR (
MONTH(c.birthdate) = 2 AND DAY(c.birthdate) = 29
AND MONTH(#suppliedDate) = 3 AND DAY(#suppliedDate) = 1
AND (YEAR(#suppliedDate) % 4 = 0) AND ((YEAR(#suppliedDate) % 100 != 0) OR (YEAR(#suppliedDate) % 400 = 0))
)

Personally I would use DATEPART instead of DATENAME as DATENAME is open to interpretation depending on locale.

If you're asking for all birthdays in a given month, then you should supply the month, not a date:
SELECT c.name
FROM cust c
WHERE datepart(m,c.birthdate) = #SuppliedMonth

I'd actually be tempted to add a birthmonth column, if you expect the list of customers to get very large. So far, the queries I've seen (including the example) will require a full table scan, as you're passing the the data column to a function and comparing that. If the table is of any size, this could take a fair amount of time since no index is going to be able to help.
So, I'd add the birthmonth column (indexed) and just do (with possible MySQLisms):
SELECT name
FROM cust
WHERE birthmonth = MONTH(NOW())
ORDER BY name;
Of course, it should be easy to set the birthmonth column either with a trigger or with your client code.

SELECT * FROM tbl_Employee WHERE DATEADD( Year, DATEPART( Year, GETDATE()) - DATEPART( Year, DOB), DOB) BETWEEN CONVERT( DATE, GETDATE()) AND CONVERT( DATE, GETDATE() + 30)
This can be use to get the upcoming Birthday by days

Related

SQL : Get last 3 month data (with only available data in the column), not from current month or today?

Anyone help me out on this scenario. I need to get a last 3 month data from particular column, which is not from current date but only from available date.
Ex :
I have one Table named Shop and column named OrderDate, In OrderDate i have only dates until 30-06-2017, but today's date is 07-02-2018. From this i need to get last 3 months data, which is Jun'17, May'17 and Apr'17.
If data available in till July'17 means i need result Jul'17,Jun'17 & May'17. And so on.
Any can help on this to achieve in SQL ?
Thanks in advance.
I assume that column OrderDate is of date or datetime datatype.
select * from Shop
where OrderDate >
(select dateadd(month, -3, max(OrderDate)) from Shop)
I think the easiest way to get this is to select the largest date in that table and use that to create the filter.
So;
Select *
from table
where date >
Dateadd
('m', -3,
( Select Max (date) from table)
)
Apologies in advance for poor formatting
You will have to find the maximum date in the table and use that:
select s.*
from Shop s,
(select convert(date,
format(
dateadd(MONTH, -3, max(OrderDate)), 'yyyyMM01')
,112) as fromDate from Shop) md
where s.OrderDate >= md.fromDate

Looking for a birthdate Range in SQL

I am looking for a birthdate range of march 21 to April 20, and the year doesn't matter. and it seems that when i search other months and date are coming out.
select * from AllStudentInfo Where
((MONTH(birthDate) >= 3 and day(birthDate) >= 21)
OR
(MONTH(birthDate) <= 4 and day(birthDate) <= 20))
AND
(BGRStatus = 'S' OR BGRStatus = 'SL')
Chances are that you want to discover up & coming dates. In any case, you can create a virtual date as follows:
SELECT DATEFROMPARTS (2017,month(birthDate),day(birthDate) as birthday
FROM AllStudentInfo
In this case, you can use:
SELECT *
FROM AllStudentInfo
WHERE DATEFROMPARTS (2017,month(birthDate),day(birthDate)
BETWEEN '2017-03-21' AND '2017-04-20';
The year 2017 is arbitrary. The point is that the dates in the BETWEEN clause are in the same year.
Using more modern techniques, you can combine it as follows:
WITH cte AS(
SELECT *,DATEFROMPARTS (2017,month(birthDate),day(birthDate) as birthDay
FROM AllStudentInfo
)
SELECT * FROM cte WHERE birthDay BETWEEN '2017-03-21' AND '2017-04-20';
The cte is a Common Table Expression which is an alternative to using a sub query.
Here is an alternative which is closer to the spirit of the question. You can use the format function to generate an expression which is purely month & day:
format(birthDate,'MM-dd')
The MM is MSSQL’s way of saying the 2-digit month number, and dd is the 2-digit day of the month.
This way you can use:
format(birthDate,'MM-dd') BETWEEN '03-21' AND '04-20'
Again as a CTE:
WITH cte AS(
SELECT *,format(birthDate,'MM-dd') as birthDay
FROM AllStudentInfo
)
SELECT * FROM cte WHERE birthDay BETWEEN '03-21' AND '04-20';
You should get the same results, but the year is completely ignored.
Switch your statement to AND
Like so
select * from AllStudentInfo Where
((MONTH(birthDate) >= 3 and day(birthDate) >= 21)
AND --Make the change here
(MONTH(birthDate) <= 4 and day(birthDate) <= 20))
AND
(BGRStatus = 'S' OR BGRStatus = 'SL')
Using OR you are querying anything that is in that date range OR that month range. And therefore, you would get results from other every months.

SQL get records in the same week

I have a table that contains records with a column indicates the Date. Given a record, I would like to select all records that are in the same week as the record. How can SQL do that?
I should say that I'm using SQLite.
You can use DATEPART with wk to get the current week. Then just check for equality.
In this case, I have also checked yy to make sure that you do not check the year of a previous week.
SELECT *
FROM TABLE
WHERE DATEPART(wk, TABLE.DATECOLUMN)
= DATEPART(wk, (SELECT DATECOLUMN FROM TABLE WHERE ID = GivenID))
AND DATEPART(yy, TABLE.DATECOLUMN) = DATEPART(yy, (SELECT DATECOLUMN FROM TABLE WHERE ID = GivenID))
UPDATE FOR SQLITE
To do this in SQLLite, Refer to this SO question and then this article that states %W is what you use to get week and %Y for year. Which gives you:
SELECT *
FROM TABLE
WHERE STRFTIME('%W', TABLE.DATECOLUMN)
= STRFTIME('%W', (SELECT DATECOLUMN FROM TABLE WHERE ID = GivenID))
AND STRFTIME('%Y', TABLE.DATECOLUMN)
= STRFTIME('%Y', (SELECT DATECOLUMN FROM TABLE WHERE ID = GivenID))
Use the datediff() function:
datediff(ww,start_date,end_date) < 1
You can use BETWEEN to specify the records you want.
SELECT * FROM records WHERE datecolumn between 'YYYY/MM/DD' AND 'YYYY/MM/DD'

SQL Current month/ year question

So I have a table that has the month and year broken down, for example field called Month has the number 7 in it (this month) and the Year field has 2011. Theres also additional months years, etc. How can I query this to show just the current year, month?
In SQL Server you can use YEAR, MONTH and DAY instead of DATEPART.
(at least in SQL Server 2005/2008, I'm not sure about SQL Server 2000 and older)
I prefer using these "short forms" because to me, YEAR(getdate()) is shorter to type and better to read than DATEPART(yyyy, getdate()).
So you could also query your table like this:
select *
from your_table
where month_column = MONTH(getdate())
and year_column = YEAR(getdate())
This should work for SQL Server:
SELECT * FROM myTable
WHERE month = DATEPART(m, GETDATE()) AND
year = DATEPART(yyyy, GETDATE())
This should work in MySql
SELECT * FROM 'my_table' WHERE 'month' = MONTH(CURRENT_TIMESTAMP) AND 'year' = YEAR(CURRENT_TIMESTAMP);
How about:
Select *
from some_table st
where st.month = to_char(sysdate,'MM') and
st.year = to_char(sysdate,'YYYY');
should work in Oracle. What database are you using? I ask because not all databases have the same date functions.
DECLARE #CMonth int=null
DECLARE #lCYear int=null
SET #lCYear=(SELECT DATEPART(YEAR,GETDATE()))
SET #CMonth=(SELECT DATEPART(MONTH,GETDATE()))
select *
from your_table
where MONTH(mont_year) = MONTH(NOW())
and YEAR(mont_year) = YEAR(NOW());
Note: (month_year) means your column that contain date format. I think that will solve your problem. Let me know if that query doesn't works.

Return just the last day of each month with SQL

I have a table that contains multiple records for each day of the month, over a number of years. Can someone help me out in writing a query that will only return the last day of each month.
SQL Server (other DBMS will work the same or very similarly):
SELECT
*
FROM
YourTable
WHERE
DateField IN (
SELECT MAX(DateField)
FROM YourTable
GROUP BY MONTH(DateField), YEAR(DateField)
)
An index on DateField is helpful here.
PS: If your DateField contains time values, the above will give you the very last record of every month, not the last day's worth of records. In this case use a method to reduce a datetime to its date value before doing the comparison, for example this one.
The easiest way I could find to identify if a date field in the table is the end of the month, is simply adding one day and checking if that day is 1.
where DAY(DATEADD(day, 1, AsOfDate)) = 1
If you use that as your condition (assuming AsOfDate is the date field you are looking for), then it will only returns records where AsOfDate is the last day of the month.
Use the EOMONTH() function if it's available to you (E.g. SQL Server). It returns the last date in a month given a date.
select distinct
Date
from DateTable
Where Date = EOMONTH(Date)
Or, you can use some date math.
select distinct
Date
from DateTable
where Date = DATEADD(MONTH, DATEDIFF(MONTH, -1, Date)-1, -1)
In SQL Server, this is how I usually get to the last day of the month relative to an arbitrary point in time:
select dateadd(day,-day(dateadd(month,1,current_timestamp)) , dateadd(month,1,current_timestamp) )
In a nutshell:
From your reference point-in-time,
Add 1 month,
Then, from the resulting value, subtract its day-of-the-month in days.
Voila! You've the the last day of the month containing your reference point in time.
Getting the 1st day of the month is simpler:
select dateadd(day,-(day(current_timestamp)-1),current_timestamp)
From your reference point-in-time,
subtract (in days), 1 less than the current day-of-the-month component.
Stripping off/normalizing the extraneous time component is left as an exercise for the reader.
A simple way to get the last day of month is to get the first day of the next month and subtract 1.
This should work on Oracle DB
select distinct last_day(trunc(sysdate - rownum)) dt
from dual
connect by rownum < 430
order by 1
I did the following and it worked out great. I also wanted the Maximum Date for the Current Month. Here is what I my output is. Notice the last date for July which is 24th. I pulled it on 7/24/2017, hence the result
Year Month KPI_Date
2017 4 2017-04-28
2017 5 2017-05-31
2017 6 2017-06-30
2017 7 2017-07-24
SELECT B.Year ,
B.Month ,
MAX(DateField) KPI_Date
FROM Table A
INNER JOIN ( SELECT DISTINCT
YEAR(EOMONTH(DateField)) year ,
MONTH(EOMONTH(DateField)) month
FROM Table
) B ON YEAR(A.DateField) = B.year
AND MONTH(A.DateField) = B.Month
GROUP BY B.Year ,
B.Month
SELECT * FROM YourTableName WHERE anyfilter
AND "DATE" IN (SELECT MAX(NameofDATE_Column) FROM YourTableName WHERE
anyfilter GROUP BY
TO_CHAR(NameofDATE_Column,'MONTH'),TO_CHAR(NameofDATE_Column,'YYYY'));
Note: this answer does apply for Oracle DB
Here's how I just solved this. day_date is the date field, calendar is the table that holds the dates.
SELECT cast(datepart(year, day_date) AS VARCHAR)
+ '-'
+ cast(datepart(month, day_date) AS VARCHAR)
+ '-'
+ cast(max(DATEPART(day, day_date)) AS VARCHAR) 'DATE'
FROM calendar
GROUP BY datepart(year, day_date)
,datepart(month, day_date)
ORDER BY 1