SQL sorting month end (mmm-yy) starting with April - sql

In SQL I am trying to convert dates to mmm-yy and then sort starting with April as the first month. So far I have managed to converted the date to mmm-yy using
SELECT
LNAME as Location,
SUBSTRING( CONVERT( VARCHAR(11), MonthEnd, 113), 4, 8) AS [MonthEnd],
CAST (TYPEDESC as VARCHAR(20)) as 'Factory',
Sum(Tonnes) as Tonnes
FROM (
SELECT
EOMONTH(X_DELIVERY_DATE) as MonthEnd,
...
but I cannot complete the final step, all I get is the date sorted alphabetically. If someone could please help!!

Let's say that you use SQL Server:
DECLARE #Temp TABLE
(
MonthEnd DATETIME
)
INSERT #Temp VALUES
('2015/01/01'),
('2015/02/01'),
('2015/03/01'),
('2015/04/01'),
('2015/05/01'),
('2015/06/01'),
('2015/07/01'),
('2015/08/01'),
('2015/09/01'),
('2015/10/01'),
('2015/11/01'),
('2015/12/01'),
('2016/01/01'),
('2016/02/01'),
('2016/03/01'),
('2016/04/01'),
('2016/05/01'),
('2016/06/01'),
('2016/07/01'),
('2016/08/01'),
('2016/09/01'),
('2016/10/01'),
('2016/11/01'),
('2016/12/01')
SELECT MonthEnd, SUBSTRING(CONVERT(VARCHAR(11), MonthEnd, 113), 4, 8)
FROM #Temp
ORDER BY YEAR(MonthEnd), (MONTH(MonthEnd) + 8) % 12

You can play with the DATEPART function
DATEPART(month, '10/5/2015')
And try this calculation:
SELECT (DATEPART(year, '3/5/2015') * 100) +
(CASE WHEN DATEPART(month, '3/5/2015') > 3
THEN DATEPART(month, '3/5/2015') - 4
ELSE DATEPART(month, '3/5/2015') + 9
END);

Related

How to cast year, month, day to date?

I have data something like this:
year (string)(Partitioned) | month (string)(Partitioned) | day (string)(Partitioned) | products
I want to cast year, month, day to only one date as date and the filter it with the following query:
SELECT year, month, day, products,
FROM X
WHERE date >= date('2020-05-01')
GROUP BY 1, 2, 3
How can I do this?
Do you talk about SQL Server? Then the best string format to cast to date is 'YYYYMMDD'. So you could cast your date numbers to strings, concatenate them and cast the result to a string again, like this:
SELECT [year], [month], [day], products
FROM X
WHERE CAST (
CAST([year] AS varchar) +
CAST([month] AS varchar) +
CAST([day] AS varchar)
AS date) >= '20200501'
GROUP BY 1, 2, 3;
You can also use the DATEFROMPARTS function which looks better:
https://learn.microsoft.com/de-de/sql/t-sql/functions/datefromparts-transact-sql?view=sql-server-ver15
SELECT [year], [month], [day], products
FROM X
WHERE DATEFROMPARTS ([year], [month], [day]) >= '20200501'
GROUP BY 1, 2, 3;
Otherwise you could convert it in a single number and compare it. This is my prefered solution:
SELECT [year], [month], [day], products
FROM X
WHERE [day] + 100*[month] + 10000*[year] >= 20200501
GROUP BY 1, 2, 3;
You can try:
cast(year || '-' || month || '-' || day as date)

Return records less than date

I have a table where 2 columns are called Month and Year and are both INT. I need to return all the records that are less than the date provided.
So if I pass the following parameters #Month = 8 and #Year = 2017, I would like to return all records before August 2017. What is the best way to achieve this?
SELECT * FROM testTable
WHERE year <= #Year AND
month < #Month
is my current SQL. This won't work if I need to display the record that is November 2014
Compare them as dates. Like this:
SELECT * FROM testTable
WHERE DATEFROMPARTS(year, month, 1) <= DATEFROMPARTS(#Year, #Month, 1)
Pass The Parameter as Date. Like
DECLARE #MyDate DATE = '08-01-2014'
Now you can go for either of the below
SELECT
*
FROM YourTable
WHERE CAST(ConCAT([Monnth],'-01-',[Year]) AS DATE) = #MyDate
Or
SELECT
*
FROM YourTable
WHERE [Year] = YEAR(#MyDate)
AND [Month] = MONTH(#MyDate)
You can use DATEPART function of SQL Server
SELECT * FROM testTable
WHERE YEAR<= DATEPART(yy,yourdate) AND
MONTH < DATEPART(mm,yourdate)
It would be better to convert data types and query further.
DECLARE #testtable TABLE (id INT identity(1, 1), name VARCHAR(100), year INT, month INT)
INSERT INTO #testtable (name, year, month)
SELECT 'me', '2014', 10
UNION
SELECT 'you', '2017', 08
UNION
SELECT 'us', '2015', 10
UNION
SELECT 'Him', '2017', 10
UNION
SELECT 'Her', '2018', 1
SELECT *
FROM #testtable
WHERE CONCAT (year, '-', right('00' + cast(Month AS VARCHAR(2)), 2), '-', '01')
< = '2017-08-01'

Select * from table where date selected is between

i trying to build the following query to select * from table where the minDate is 03-02-2014 and the maxDate is 01-03-2014
but something i missing.
hope that someone can help me with this.
SELECT * From table Where
SUBSTRING(mydate, 1, 10) >= REPLACE('03-02-2014','-','/') AND
SUBSTRING(mydate, 1, 10) <= REPLACE('01-03-2014','-','/')
Note:
My Date column is of type varchar with a value like this --> 03/02/2014 18:13:16
im working in sql server management studio (t-sql)
From your comments, it seems that the mydate column of your table is in the British format.
Read this article about date conversion in SQL SERVER to understand more about date conversions.
Also updated my answer with the date conversions for this format.
Try something like
SELECT * FROM table
WHERE CONVERT(DATE, SUBSTRING(mydate, 1, 10), 103) >= CONVERT(DATE, '03/02/2014', 103)
AND CONVERT(DATE, SUBSTRING(mydate, 1, 10), 103) <= CONVERT(DATE, '01/03/2014', 103)
you can do something like:
Select * From Table
Where CONVERT( Datetime, mydate ,110 ) between CONVERT( Datetime, #min ,110 ) and between CONVERT( Datetime, #max ,110 )
I don't have SSMS available right now, but for a quick try you might try this
SELECT * From table Where
CAST( SUBSTRING(mydate, 1, 10) as date) BETWEEN CAST( SUBSTRING('START DATE', 1, 10) as date)
AND CAST( SUBSTRING('END DATE', 1, 10) as date)

How I can select / sort dates by period intervals?

For ex:
If we have in table records like:
25/06/2009
28/12/2009
19/02/2010
16/04/2011
20/05/2012
I want to split/select this dates according to 6 month intervals starting from current date.
result should be like:
0-6 month from now: first record
7-12 month from now: second record
...
It will be much apreciated if you make this simple as I made it very stupid and complicated like:
declare variable like t1=curdate()+6
t2=curdate()+12
...
then selected records to fit between curdate() and t1, then t1 and t2 etc.
Thanks,
r.
CORRECTION: Had it backwards, Need to use Modulus, not integer division - sorry...
If MonthCount is a calculated value which counts the number of months since a specific Dec 31, and mod is modulus division (output the remainder after dividing)
Select [Column list here]
From Table
Group By Case When MonthCount Mod 12 < 6
Then 0 Else 1 End
In SQL Server, for example, you could use the DateDiff Function
Select [Column list here]
From Table
Group By Case When DateDiff(month, myDateColumn, curdate) % 12 < 6
Then 0 Else 1 End
( in SQL Server the percent sign is the modulus operator )
This will group all the record into buckets which each contain six months of data
SELECT (DATEDIFF(MONTH, thedate, GETDATE()) / 6) AS semester,
SUM(receipt)
FROM thetable
GROUP BY semester
ORDER BY semester
the key idea is grouping and ordering by the expression that gives you the "semester".
This question really baffled me, cos I couldn't actually come up with a simple solution for it. Damn.
Best I could manage was an absolute bastardization of the following where you create a Temp Table, insert the "Periods" into it, join back to your original table, and group off that.
Assume your content table has the following
ID int
Date DateTime
Counter int
And you're trying to sum all the counter's in six month periods
DECLARE #min_date datetime
select #min_date = min(date) from test
DECLARE #max_date datetime
select #max_date = max(date) from test
DECLARE #today_a datetime
DECLARE #today_b datetime
set #today_a = getdate()
set #today_b = getdate()
CREATE TABLE #temp (startdate DateTime, enddate DateTime)
WHILE #today_a > #min_date
BEGIN
INSERT INTO #temp (startDate, endDate) VALUES (dateadd(month, -6, #today_a), #today_a)
SET #today_a = dateadd(month, -6, #today_a)
END
WHILE #today_b < #max_date
BEGIN
INSERT INTO #temp (startDate, endDate) VALUES (#today_b, dateadd(month, 6, #today_b))
SET #today_b = dateadd(month, 6, #today_b)
END
SELECT * FROM #temp
SELECT
sum(counter),
'Between ' + Convert(nvarchar(10), startdate, 121) + ' => ' + Convert(nvarchar(10), enddate, 121) as Period
FROM test t
JOIN #Temp ht
ON t.Date between ht.startDate AND ht.EndDate
GROUP BY
'Between ' + Convert(nvarchar(10), startdate, 121) + ' => ' + Convert(nvarchar(10), enddate, 121)
DROP TABLE #temp
I really hope someone can come up with a better solution my brain has obviously melted.
Not quite what you're attempting to accomplish, but you could use the DATEDIFF function to distinguish the ranging of each record:
SELECT t.MonthGroup, SUM(t.Counter) AS TotalCount
FROM (
SELECT Counter, (DATEDIFF(m, GETDATE(), Date) / 6) AS MonthGroup
FROM Table
) t
GROUP BY t.MonthGroup
This would create a sub query with an expression that expresses the date ranging group you want. It would then group the sub-query by this date ranging group and you can then do whatever you want with the results.
Edit: I modified the example based on your example.
If you're using SQL Server:
SELECT *,
(
FLOOR
(
(
DATEDIFF(month, GETDATE(), date_column)
- CASE WHEN DAY(GETDATE()) > DAY(date_column) THEN 1 ELSE 0 END
) / 6.0
) * 6
) AS SixMonthlyInterval
FROM your_table
If you're using MySQL:
SELECT *,
(
FLOOR
(
(
((YEAR(date_column) - YEAR(CURDATE())) * 12)
+ MONTH(date_column) - MONTH(CURDATE())
- CASE WHEN DAY(CURDATE()) > DAY(date_column) THEN 1 ELSE 0 END
) / 6.0
) * 6
) AS SixMonthlyInterval
FROM your_table

Get month and year from a datetime in SQL Server 2005

I need the month+year from the datetime in SQL Server like 'Jan 2008'. I'm grouping the query by month, year. I've searched and found functions like datepart, convert, etc., but none of them seem useful for this. Am I missing something here? Is there a function for this?
select
datepart(month,getdate()) -- integer (1,2,3...)
,datepart(year,getdate()) -- integer
,datename(month,getdate()) -- string ('September',...)
If you mean you want them back as a string, in that format;
SELECT
CONVERT(CHAR(4), date_of_birth, 100) + CONVERT(CHAR(4), date_of_birth, 120)
FROM customers
Here are the other format options
Beginning with SQL Server 2012, you can use:
SELECT FORMAT(#date, 'yyyyMM')
Use:
select datepart(mm,getdate()) --to get month value
select datename(mm,getdate()) --to get name of month
In SQL server 2012, below can be used
select FORMAT(getdate(), 'MMM yyyy')
This gives exact "Jun 2016"
Funny, I was just playing around writing this same query out in SQL Server and then LINQ.
SELECT
DATENAME(mm, article.Created) AS Month,
DATENAME(yyyy, article.Created) AS Year,
COUNT(*) AS Total
FROM Articles AS article
GROUP BY
DATENAME(mm, article.Created),
DATENAME(yyyy, article.Created)
ORDER BY Month, Year DESC
It produces the following ouput (example).
Month | Year | Total
January | 2009 | 2
How about this?
Select DateName( Month, getDate() ) + ' ' + DateName( Year, getDate() )
That format doesn't exist. You need to do a combination of two things,
select convert(varchar(4),getdate(),100) + convert(varchar(4),year(getdate()))
( Month(Created) + ',' + Year(Created) ) AS Date
the best way to do that is with :
dateadd(month,datediff(month,0,*your_date*),0)
it will keep your datetime type
cast(cast(sq.QuotaDate as date) as varchar(7))
gives "2006-04" format
The question is about SQL Server 2005, many of the answers here are for later version SQL Server.
select convert (varchar(7), getdate(),20)
--Typical output 2015-04
SQL Server 2005 does not have date function which was introduced in SQL Server 2008
returns the full month name, -, full year e.g. March-2017
CONCAT(DATENAME(mm, GetDate()), '-', DATEPART(yy, GetDate()))
I had the same problem and after looking around I found this:
SELECT DATENAME(yyyy, date) AS year
FROM Income
GROUP BY DATENAME(yyyy, date)
It's working great!
Converting the date to the first of the month allows you to Group By and Order By a single attribute, and it's faster in my experience.
declare #mytable table(mydate datetime)
declare #date datetime
set #date = '19000101'
while #date < getdate() begin
insert into #mytable values(#date)
set #date = dateadd(day,1,#date)
end
select count(*) total_records from #mytable
select dateadd(month,datediff(month,0,mydate),0) first_of_the_month, count(*) cnt
from #mytable
group by dateadd(month,datediff(month,0,mydate),0)
---Lalmuni Demos---
create table Users
(
userid int,date_of_birth date
)
---insert values---
insert into Users values(4,'9/10/1991')
select DATEDIFF(year,date_of_birth, getdate()) - (CASE WHEN (DATEADD(year, DATEDIFF(year,date_of_birth, getdate()),date_of_birth)) > getdate() THEN 1 ELSE 0 END) as Years,
MONTH(getdate() - (DATEADD(year, DATEDIFF(year, date_of_birth, getdate()), date_of_birth))) - 1 as Months,
DAY(getdate() - (DATEADD(year, DATEDIFF(year,date_of_birth, getdate()), date_of_birth))) - 1 as Days,
from users
Yes, you can use datename(month,intime) to get the month in text.
,datename(month,(od.SHIP_DATE)) as MONTH_
Answer:
MONTH_
January
January
September
October
December
October
September
It's work great.
DECLARE #pYear VARCHAR(4)
DECLARE #pMonth VARCHAR(2)
DECLARE #pDay VARCHAR(2)
SET #pYear = RIGHT(CONVERT(CHAR(10), GETDATE(), 101), 4)
SET #pMonth = LEFT(CONVERT(CHAR(10), GETDATE(), 101), 2)
SET #pDay = SUBSTRING(CONVERT(CHAR(10), GETDATE(), 101), 4,2)
SELECT #pYear,#pMonth,#pDay
The following works perfectly! I just used it, try it out.
date_format(date,'%Y-%c')