Order by birthday, disregarding year - sql

How do you make a query where you ORDER BY birthday disregarding the year altogether. I need to eliminate/disregard the year and ORDER BY birthdate month and birthdate day from today's date in either ASC or DESC.
The below won't work because the years of the birthdate come into play. The below example shows what happens when the year is regarded:
John 01/02/1974
Billy 11/15/2000
Ally 06/25/2008
SELECT * FROM users ORDER BY birthdate
Expected results when ordering by birthday:
John 01/02/1974
Ally 06/25/2008
Billy 11/15/2000

EDIT: #AaronBertrand's comment is correct, day-of-year doesn't hold for leap years. You could use his solution. Another way is to order by month and day, like:
SELECT * FROM users ORDER BY month(birthdate), day(birthdate)

This will normalize all dates to the year 2000:
ORDER BY DATEADD(YEAR, 2000-YEAR(birthday), birthday);
This will handle leap year babies correctly.

Try
SELECT * FROM users ORDER BY SUBSTRING(birthdate, 1, 5);

Try this query
It order the birthdate in ascending order
SELECT `id`, `teacher_name`, `phn_num`, `date_of_birth`, `date_of_birth` + INTERVAL(YEAR(CURRENT_DATE()) - YEAR(`date_of_birth`)) + 0 YEAR AS currbirthday, `date_of_birth` + INTERVAL(YEAR(CURRENT_DATE()) - YEAR(`date_of_birth`)) + 1 YEAR AS nextbirthday FROM `teacher_details` ORDER BY CASE WHEN currbirthday >= CURRENT_DATE() THEN currbirthday ELSE nextbirthday END

Related

Remove Duplicates and show Total sales by year and month

i am trying to work with this query to produce a list of all 11 years and 12 months within the years with the sales data for each month. Any suggestions? this is my query so far.
SELECT
distinct(extract(year from date)) as year
, sum(sale_dollars) as year_sales
from `project-1-349215.Dataset.sales`
group by date
it just creates a long list of over 2000 results when i am expecting 132 max one for each month in the years.
You should change your group by statement if you have more results than you expected.
You can try:
group by YEAR(date), MONTH(date)
or
group by EXTRACT(YEAR_MONTH FROM date)
A Grouping function is for takes a subsection of the date in your case year and moth and collect all rows that fit, and sum it up,
So a sĀ“GROUp BY date makes no sense, what so ever as you don't want the sum of every day
So make this
SELECT
extract(year from date) as year
,extract(MONTH from date) as month
, sum(sale_dollars) as year_sales
from `project-1-349215.Dataset.sales`
group by 1,2
Or you can combine both year and month
SELECT
extract(YEAR_MONTH from date) as year
, sum(sale_dollars) as year_sales
from `project-1-349215.Dataset.sales`
group by 1

group by year month in postgresql

customer Date location
1 25Jan2018 texas
2 15Jan2018 texas
3 12Feb2018 Boston
4 19Mar2017 Boston.
I am trying to find out count of customers group by yearmon of Date column.Date column is of text data type
eg: In jan2018 ,the count is 2
I would do something like the following:
SELECT
date_part('year', formattedDate) as Year
,date_part('month', formattedDate) as Month
,count(*) as CustomerCountByYearMonth
FROM
(SELECT to_date(Date,'DDMonYYYY') as formattedDate from <table>) as tbl1
GROUP BY
date_part('year', formattedDate)
,date_part('month', formattedDate)
Any additional formatting for dates could be done on the inner query that will allow for adjustments in case some single digit days need to be padded or a month has four letters instead of three etc.
By converting to date type, you can properly order by date type and not alphabetical etc.
Optionally:
SELECT
Year
,Month
,count(*) as CustomerCountByYearMonth
FROM
(SELECT
date_part('year', to_date(Date,'DDMonYYYY')) as Year
,date_part('month', to_date(Date,'DDMonYYYY')) as Month
FROM <table>) as tbl1
GROUP BY
Year
,Month
You shouldn't store dates in a text column...
select substring(Date, length(Date)-6), count(*)
from tablename
group by substring(Date, length(Date)-6)
I thought #Jarlh asked a good question -- what about dates like January 1? Is it 01Jan2019 or 1Jan2019? If it can be either, perhaps a regex would work.
select
substring (date from '\d+(\D{3}\d{4})') as month,
count (distinct customer)
from t
group by month
The 'distinct customer' also presupposes you may have the same customer listed in the same month, but you only want to count it once. If that's not the case, just remove 'distinct.'
And, if you wanted the output in date format:
select
to_date (substring (date from '\d+(\D{3}\d{4})'), 'monyyyy') as month,
count (distinct customer)
from t
group by month
If it is a date column, you can truncate the date:
select date_trunc('month', date) as yyyymm, count(*)
from t
group by yyyymm
order by yyyymm;
I really read that the type was date. For a string, just use string functions:
select substr(date, 3, 7) as mmmyyyy, count(*)
from t
group by mmmyyyy;
Unfortunately, ordering doesn't work in this case. You should really be storing dates using the proper type.

Calculate totals of field based on current fiscal year only - SQL

I have seen many examples regarding calculating the sum of fields using the fiscal year, but I can not find one that fits my needs. What I am trying to do is get just the current fiscal year totals for a field using SQL Query. The fields I have is userid, startdate, total_hours, and missed_hours. Here is the query I have so far:
SELECT
userid,
SUM(total_hours) - SUM(missed_hours) AS hours
FROM mytable
GROUP BY userid
This works great, but all I need is the total number of hours for the current fiscal year for each of the userid's. Our fiscal year runs from July to June. I only need the current fiscal year and I need it to start over again this coming July.
Assuming this is SQLServer, try:
SELECT userid, SUM(total_hours) - SUM(missed_hours) AS hours
FROM mytable
WHERE startdate >= cast( cast(year(dateadd(MM,-6,getdate())) as varchar(4)) +
'-07-01' as date ) and
startdate < cast( cast(year(dateadd(MM, 6,getdate())) as varchar(4)) +
'-07-01' as date )
GROUP BY userid
Add a where clause:
FROM mytable
WHERE startdate >= '2011-07-01'
GROUP BY userid
Or with the start of the year dynamically:
where startdate >= dateadd(yy, datepart(yy, getdate())-2001, '2000-07-01')
Maybe something like this:
SELECT
userid,
SUM(total_hours) - SUM(missed_hours) AS hours
FROM
mytable
WHERE
MONTH(startdate) BETWEEN 6 AND 7
AND YEAR(startdate) IN (2011,2012)
GROUP BY userid
For the solution, two additional information is needed
the name of the date column
the vendor type of RDBMS you are using
I supposed your date column is date_col and you are using MySQL
SELECT
userid,
SUM(total_hours) - SUM(missed_hours) AS hours
FROM mytable
WHERE date_col between STR_TO_DATE('01,7,2011','%d,%m,%Y') and STR_TO_DATE('01,7,2010','%d,%m,%Y')
GROUP BY userid

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

Sql query to find date period between multiple rows

I have a table with three columns (City_Code | Start_Date | End_Date).
Suppose i have the following data:
New_York|01/01/1985|01/01/1987
Paris|02/01/1987|01/01/1990
San Francisco|02/01/1990|04/01/1990
Paris|05/01/1990|08/01/1990
New_York|09/01/1990|11/01/1990
New_York|12/01/1990|19/01/1990
New_York|20/01/1990|28/01/1990
I would like to get the date period for which someone lived in the last city of his residence. In this example that is New_York(09/01/1990-28/01/1990) using only sql. I can get this period by manipulating the data with java , but is it possible to do it with plain sql?
Thanks in advance
You can grab the first and last date of residence by city using this:
SELECT TOP 1 City_Code, MIN(Start_Date), Max(End_Date)
FROM Table
GROUP BY City_Code
ORDER BY Max(End_Date) desc
but, the problem is that the start date will be the first date of residence in the city in question.
For 10g you don't have the option of SELECT TOP n so you must be a little creative.
WITH last_period
AS
(SELECT city, moved_in, moved_out, NVL(moved_in-LEAD(moved_out, 1) OVER (ORDER BY city), 0) AS lead
FROM periods
WHERE city = (SELECT city FROM periods WHERE moved_out = (SELECT MAX(moved_out) FROM periods)))
SELECT city, MIN(moved_in) AS moved_in, MAX(moved_out) AS moved_out
FROM last_period
WHERE lead >= 0
GROUP BY city;
This works for the example dataset that you have given. It could stand some optimisation for a large dataset but gives you a working example, tested on Oracle 10g.
If it's MySQL, you can easily use
TIME_TO_SEC(TIMEDIFF(end_date, start_date)) AS `diff_in_secs`
Having time difference in seconds you go any further.
On SQL Server, couldn't you use:
SELECT TOP 1 City_Code, Start_Date + "-" + End_Date
FROM MyTable
ORDER BY enddate DESC
That would get the date period and city with the latest end date.
This is assuming you are trying to just find the city where the person most recently lived, formatted with a dash.
Given that this is Oracle, you can simply subtract the end date and start date to get the number of days in between.
Select City_Code, (End_Date - Start_Date) Days
From MyTable
Where Start_Date = (
Select Max( T1.Start_ Date )
From MyTable As T1
)
If you are using SQL Server you can use the DateDiff() function
DATEDIFF ( datepart , startdate , enddate )
http://msdn.microsoft.com/en-us/library/ms189794.aspx
EDIT
I don't know Oracle but I did find this article
SELECT
MAX(t.duration)
FROM (
SELECT
(End_Date - Start_Date) duration
From
Table
) as t
I hope this will work.
If you want to calculate only the last period length for the last city of residence, then it's probably something like this:
SELECT TOP 1
City_Code,
End_Date - Start_Date AS Days
FROM atable
ORDER BY Start_Date DESC
But if you mean to include all the periods the person has ever lived in a city that happens to be their last city of residence, then it's a bit more complicated, but not too much:
SELECT TOP 1
City_Code,
SUM(End_Date - Start_Date) AS Days
FROM atable
GROUP BY City_Code
ORDER BY MAX(Start_Date) DESC
But the above solution most probably returns the last city information only after it calculates the data for all cities. Do we need that? Not necessarily, so maybe we should use another approach. Maybe like this:
SELECT
City_Code,
SUM(End_Date - Start_Date) AS Days
FROM atable
WHERE City_Code = (SELECT TOP 1 City_Code FROM atable ORDER BY Start_Date DESC)
GROUP BY City_Code
i'm short on time - but this feels like you could use the window function LAG to compare to the previous row and retain the appropriate begin date from that row when the city changes, and dont change it when the city is the same - this should correctly preserve the range.