Its really frustrating whenever I have to work with date/ datetime datatypes and SQL doesn't provide a good and easy way to work with it.
Currently I have this table RecordsDaily with a column Date with datatype date. I want to convert the Date column to month and take only distinct month values AND then sort according to month. Below is the query.
select distinct(CAST(DATEPART(year,Date) as varchar(10)) + ' ' + datename(MONTH,Date)) Month
from P98.dbo.RecordsDaily
where Date >= '2013/12/1'
order by Month
Obviously since I have made it varchar it doesn't consider it as date datatype and sorts it alphabetically as below.
Month
2013 December
2014 April
2014 February
2014 January
2014 March
2014 May
Any help to make it sort as per calendar.
UPDATE
Please note the output should be with Month and Year
Please try:
select Month from(
select distinct(CAST(DATEPART(year,Date) as varchar(10)) + ' ' + datename(MONTH,Date)) Month
,year(Date) yr, month(Date) mn
from P98.dbo.RecordsDaily
where Date >= '2013/12/1'
)x
order by yr, mn
try this !
select * from table order by cast(('01'+id) as datetime)asc
-- id is your column_name
Related
I am trying to write a SQL query to get data for last year. I don't have a date column in my table, but have Year and WeekNo. Suppose this is WeekNo 26 in Year 2017, I need to get the data from WeekNo 26 Year 2016 to WeekNo 26 Year 2017.
Columns in my table are:
Year WeekNo YearWeek(Eg 2016 26) DataX
Thanks for the help in advance!
If this is SQL Server. Give this a try. This will get you the Week #, Current Year and Previous Year to put into your query.
Select DatePart(Week,GetDate()) as WeekNo
, Year(GetDate()) as CurrentYear
, Year(DateAdd(Year,-1,GetDate())) as PreviousYear
Guessing this might be what you are looking for, assuming SQL Server:
Select T1.Year
,T1.WeekNo
,T1.DataX
From MyTable T1
Where (T1.Year = Year(GetDate())
AND T1.WeekNo <= DatePart(Week,GetDate())
)
OR (T1.Year = Year(GetDate()) -1
AND T1.WeekNo >= DatePart(Week,GetDate())
)
This is inclusive of the same week, last year, is your want this to be exclusive of that week, change the ">=" to ">"
I have a query that sales and it shows the month and year (field names are salemonth & saleyear) of the sale. Example return-set would be
January 2014
February 2014
March 2014
December 2014
January 2015
Now obviously I can't set it that way in my straight query as if I try to order by salemonth ASC it woudl show December, February, january, january, March. or even if I order by year ASC it still would not show in the actual calendar month order. How can I sort this result set to show in the order of an actual calendar?
One caveat their may be 0 sales for the month (november for example) I would still want this month/year shown in the query but have a 0 shown. Is this achievable?
A quick idea and fix (not the prettiest of solutions):
SELECT *, CAST(([Month] + ' 1,' + [Year]) AS Datetime) AS OrderDate FROM [TABLE] ORDER BY OrderDate
..or if you prefer to hide the sorting column:
SELECT * FROM [TABLE] ORDER BY CAST(([Month] + ' 1,' + [Year]) AS Datetime)
This is assuming the values are stored as some type of varchar/string, otherwise you'd obviously need to cast a few more bits.
I want to display a below data in order by first take month and then year
count Date
------- ----------
5 Aug 2011
6 jan 2008
10 feb 2009
I want to result as a first display a 2008 year, then 2009 like wise ordering wise date and also should display month in order wise
Assumptions:
You are trying to count records grouping by year and month
You have a table named Table1 with a column named EventDate
You are using SQL Server (you didn't specify)
You don't mind having extra columns in the output (you can ignore the columns you don't need)
You want to order by count, then year, then month
Based on these assumptions, the following should give you what you want.
SELECT COUNT(*) AS Count,
CONVERT(CHAR(3), DATENAME(MONTH, EventDate))
+ ' ' + CONVERT(CHAR(4), YEAR(EventDate)) AS Date,
MIN(YEAR(EventDate)) AS Year, MIN(MONTH(EventDate)) AS Month
FROM Table1
GROUP BY CONVERT(CHAR(4), YEAR(EventDate)),
CONVERT(CHAR(3), DATENAME(MONTH, EventDate))
ORDER BY COUNT(*), Year, Month
Here is the solution..
select convert(char(3), Date, 0)+' '+RIGHT(CONVERT(varchar, YEAR(Date)), 4) as [Date]
,count(id) as Count from Tabletest
group by convert(char(3), Date, 0)+' '+ RIGHT(CONVERT(varchar, YEAR(Date)), 4),month(Date),YEAR(Date)
order by YEAR(Date),MONTH(Date)
If today is say 15th August 2012 then the query should return the following
15/01/2011,
15/02/2011,
...
...
15/07/2012
15/08/2012
If today is 31st August 2012 then the query would return
31/01/2011,
28/02/2011, <<<<this is the nearest date
...
...
31/07/2012
31/08/2012
We have a vw_DimDate in our Warehouse which should help
edit
It contains the following fields
Currently I'm using the following but it seems rather convoluted! ...
DECLARE #Dt DATETIME = '31 JUL 2012'--GETDATE()
;WITH DateSet_cte(DayMarker)
AS
(
SELECT DayMarker
FROM WHData.dbo.vw_DimDate
WHERE
DayMarker >= CONVERT(DATETIME,CONVERT(CHAR(4),DATEADD(YEAR,-1,#Dt),112) + '0101') AND
DayMarker <=#Dt
)
, MaxDate_cte(MaxDate)
AS
(
SELECT [MaxDate] = MAX(DayMarker)
FROM DateSet_cte
)
SELECT
[Mth] = CONVERT(DATETIME,CONVERT(CHAR(6),a.DayMarker,112) + '01')
, MAX(a.DayMarker) [EquivDate]
FROM DateSet_cte a
WHERE DAY(a.DayMarker) <= (SELECT DAY([MaxDate]) FROM MaxDate_cte)
GROUP BY CONVERT(DATETIME,CONVERT(CHAR(6),a.DayMarker,112) + '01')
;with Numbers as (
select distinct number from master..spt_values where number between 0 and 23
), Today as (
select CONVERT(date,CURRENT_TIMESTAMP) as d
)
select
DATEADD(month,-number,d)
from
Numbers,Today
where DATEPART(year,DATEADD(month,-number,d)) >= DATEPART(year,d) - 1
Seems odd to want a variable number of returned values based on how far through the year we are, but that's what I've implemented.
When you use DATEADD to add months to a value, then it automatically adjusts the day number if it would have produced an out of range date (e.g. 31st February), such that it's the last day of the month. Or, as the documentation puts it:
If datepart is month and the date month has more days than the return month and the date day does not exist in the return month, the last day of the return month is returned.
Of course, if you already have a numbers table in your database, you can eliminate the first CTE. You mentioned that you "have a vw_DimDate in our Warehouse which should help", but since I have no idea on what that (presumably, a) view contains, it wasn't any help.
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