SQL Server sort by date - sql

I have a table of transactions in SQL Server 2016 with a column called mthweekyr where each row in this column has as a string, the month number, week number of the month, and year of the transaction, where week number is determined by day of the month / 7.
For example, if the transaction date was: 2018-09-28, this would appear as 9-4-2018.
The problem is that the original transaction date column is not actually in the table, and I would like to sort these transactions by the mthweekyr column, but am unable to do so because this column is not a date type, it is a string type. (I don't make the tables, I just use them!)
Any suggestions on how to proceed?
Thanks.

Here's another way...
declare #table table(mthweekyr varchar(10))
insert into #table
values
('9-4-2018'),
('8-4-2018'),
('9-5-2018'),
('7-5-2018'),
('7-4-2018'),
('9-5-2017'),
('9-4-2017')
select *
from #table
order by
cast(right(mthweekyr,4) as int) --order by year first
,cast(left(mthweekyr,charindex('-',mthweekyr)-1) as int) --order by month. Works for single or double digit months
,left(right(mthweekyr,6),1) --order by week number which is always a single digit, since it's the week number of the month not the year.

Late answer, but perhaps a thinner alternative.
You can simply use the implicit conversion of m-d-y to date
Example
declare #table table(mthweekyr varchar(10))
insert into #table
values
('9-4-2018'),
('8-4-2018'),
('9-5-2018'),
('7-5-2018'),
('7-4-2018'),
('9-5-2017'),
('9-4-2017'),
('10-4-2017'), -- added 2 digit month
('10-5-2017') -- added 2 digit month
Select *
From #table
Order By convert(date,mthweekyr)
Returns
mthweekyr
9-4-2017
9-5-2017
10-4-2017
10-5-2017
7-4-2018
7-5-2018
8-4-2018
9-4-2018
9-5-2018

Using JNevill's suggestion you could leverage PARSENAME for this.
declare #Date varchar(20) = '9-4-2018'
select PARSENAME(replace(#Date, '-', '.'), 1) + '-' + right('00' + PARSENAME(replace(#Date, '-', '.'), 3), 2) + '-' + right('00' + PARSENAME(replace(#Date, '-', '.'), 2), 2)
This returns 2018-09-04
You could also do some string manipulation but that starts to get rather tedious.

obviously not the most efficient I'm sure but to brute force it...
order by substring(#theStr, len(#theStr) - 4 + 1, 4)
+ substring(#thestr, charindex('-',#Thestr)+1,1)
+ right('00' + substring(#thestr, 1, charindex('-',#Thestr)-1),2)
here's how to get there by pieces:
declare #thestr varchar(255) = '9-4-2018'
Declare #SortStr as Varchar(255)
--year
Select #SortStr = substring(#theStr, len(#theStr) - 4 + 1, 4)
print #Sortstr
--day
Select #SortStr = right('00' + substring(#thestr, 1, charindex('-',#Thestr)-1),2)
print #sortStr
--week
Select #SortStr = substring(#thestr, charindex('-',#Thestr)+1,1)
print #sortStr
Select #SortStr = substring(#theStr, len(#theStr) - 4 + 1, 4)
+ substring(#thestr, charindex('-',#Thestr)+1,1)
+ right('00' + substring(#thestr, 1, charindex('-',#Thestr)-1),2)
will yield this output
2018
09
4
2018409

Since you know what the algorithm for date hashing is you can restore the original dates into a new column and then sort on it. Something like:
SELECT *, CONVERT(datetime2(1),
RIGHT(#mthweekyr, 4) + '-' +
LEFT(#mthweekyr, CHARINDEX('-', #mthweekyr) - 1) + '-' +
SUBSTRING(#mthweekyr, CHARINDEX('-', #mthweekyr) + 1,
CHARINDEX('-', #mthweekyr, CHARINDEX('-', #mthweekyr) + 1)
- CHARINDEX('-', #mthweekyr) - 1)) AS EstimatedDate
FROM theTable
ORDER BY EstimatedDate
UPDATE
So the above is the long, harder way.
A smarter approach would be to leave the heavy lifting to the SQL Engine and use the third parameter of the CONVERT function, which specifies the style of the input. As the mthweekyr basically represents a USA style of mm-d-yyyy, the query will look like:
SELECT *, CONVERT(datetime2(1), mthweekyr, 110) AS EstimatedDate
FROM theTable
ORDER BY EstimateDate

Related

How can I convert an integer like 3212007 to date 3-21-2007 uisng IBM DB2 SQL?

The dataset I inherited has a DATE column but the values in this column are integers of the form 3212007 which should be 03-21-2007. I can't get it back into date format.
I can convert the integer to a string using CAST(myinteger as varchar(8)) without difficulty. Then I can CAST that as date by CAST(CAST(myinteger as varchar(8)) as date) which gets me a date. The problem is that my integer is formatted as 'mmddyyyy' so for 3212007, I get 3212-01-07.
select TRANSACTION_DATE from MA_NORFOLK fetch first row only;
[returns: 3212007]
select CAST(TRANSACTION_DATE as VARCHAR) from MA_NORFOLK fetch first row only;
[returns: 3212007]
select CAST(CAST(TRANSACTION_DATE as varchar(8)) as date) from MA_NORFOLK fetch first row only;
[returns: 3212-01-07]
Other posts suggest using CONVERT command, but all I get are errors
"DATE" is not valid in the context where it is used..."
Could you please advise me?
Try this:
date(to_date(digits(dec(3212007, 8)), 'MMDDYYYY'))
If you may have one digit for month, there is an alternative:
select
date
(
case when substr(char_dt, 1, 2)='00'
then translate('EFGH-0D-0C', char_dt, 'ABCDEFGH')
else translate('EFGH-AB-CD', char_dt, 'ABCDEFGH')
end
) dt, char_dt
from
(
select digits(dec(i, 8)) char_dt
from table(values 3212007, 312007) t(i)
) t;
DT CHAR_DT
---------- --------
2007-03-21 03212007
2007-01-03 00312007
This works (at least in MS SQL Server):
SELECT CAST(CONCAT( RIGHT(3212007,4),'-',
(3212007 / 1000000), '-', ((3212007 % 1000000) / 10000)) AS date)
The trick is that you don't know if you will have a single digit, or two-digit month, so you have to start with getting just the right 4 characters as the year. Then by using combinations of modulo and integer divide, you can parse out the month and day.
Of course, you will want to substitute your actual date column for the sample data that I used above.
I think this may works well:
create table #temp(
date int
)
insert into #temp (date)
values(3212007),
(12032019)
select
case when len(cast(date as varchar)) = 7
then
'0' + left(cast(date as varchar), 1) + '-' + substring(cast(date as varchar), 2,2) + '-' + right(cast(date as varchar), 4)
else left(cast(date as varchar), 2) + '-' + substring(cast(date as varchar), 3,2) + '-' + right(cast(date as varchar), 4) end
from #temp

How convert SQL Server DATE columns to DD:MM:YY and HH:MM:SS

I have a SQL Server column which is called DATE with this sample data 19452801102747.
I have this code
SELECT REPLACE(CONVERT(CHAR(10), [DATE], 103), '/', '')
I can get the date okay, is the final part of converting HH:MM:SS.
I am using SSMS 2018 and I would like to have two column separate; columns as shown on below image (DATE(DD:MM:YYYY))(TIME(HH:MM:SS))
Many thanks for your help.
We can use a simple substring to add date time separator in your varchar string,
because we cannot directly convert varchar to datetime..
DECLARE #date varchar(50) = '19452801102747' declare #date1 varchar(50)
SET
#date1 = SUBSTRING(#date, 1, 4) + '-' + substring(#date, 7, 2) + '-' + substring(#date, 5, 2) + ' ' + substring(#date, 9, 2) + ':' + substring(#date, 11, 2) + ':' + substring(#date, 13, 2)
SELECT convert(datetime, #date1)
First of all: You should not store datetime values in a non-appropriate datatype.
Your example looks like YYYYddMMHHmmss. There is no out of the box conversion for this...
The following will perform a number of string methods in order to transform your own format to a standard format. In this case I chose ISO8601, which is YYYY-MM-ddTHH:mm:ss:
DECLARE #YourDate VARCHAR(100)='19452801102747';
SELECT CONVERT(DATETIME,STUFF(LEFT(#YourDate,4) + STUFF(STUFF(STUFF(STUFF(SUBSTRING(#YourDate,7,1000),7,0,':'),5,0,':'),3,0,'T'),1,0,'-'),8,0,'-' + SUBSTRING(#YourDate,5,2)),126);
The STUFF() calls will insert some characters in the right position. Furthermore some string cutting will swap your ddMM to MMdd.

SQL Server : converting varchar field to date

I have in my table a varchar column with bunch of dates in the following format dd-MM-yyyy
31-12-2018
01-01-2019
02-01-2019
I need to write a date based query that gets all the dates before 01-01-2019.
I have tried using both CAST and CONVERT to convert these table values without luck.
Using CAST, my code is below:
SELECT
CAST('''' + SUBSTRING(arc_billed_to_date, 4, 2) + '-' + SUBSTRING(arc_billed_to_date, 1, 2) + SUBSTRING(arc_billed_to_date, 6, 5)+ '''' AS date),
CAST('''' + SUBSTRING(arc_billed_to_date, 7, 5) + '-' + SUBSTRING(arc_billed_to_date, 1, 2) + '-' + SUBSTRING(arc_billed_to_date, 4, 2) + '''' AS date),
CAST('''' + SUBSTRING(arc_billed_to_date, 7, 5) + '-' + SUBSTRING(arc_billed_to_date, 4, 2) + '-' + SUBSTRING(arc_billed_to_date, 1, 2) + '''' AS DATE),
CONVERT(DATE, '12-31-2018') AS x
FROM
wkpol
Using Convert
select Convert(datetime,'''' + SUBSTRING(arc_billed_to_date,7,5) + '-' + SUBSTRING(arc_billed_to_date,4,2) + '-' + SUBSTRING(arc_billed_to_date,1,2)+ '''',105) as x from wkpol
The error I get is
Conversion failed when converting date and/or time from character string.
Any help is appreciated.
SELECT *
FROM wkpol
WHERE convert(date, arc_billed_to_date, 103) < convert(date, '01/01/2019');
Well you are going to get many blames for using varchar field for date. Anyway, assuming it is a matter of another thread you can do the conversion like:
select * from myTable
where cast(right(arc_billed_to_date,4) +
substring(arc_billed_to_date,4,2) +
left(arc_billed_to_date,2) as date) < '20190101';
You wouldn't be using any index either.
In addition to Sean's comments, you can also set the DateFormat as DMY
Example
Declare #YourTable table (SomeCol varchar(50))
Insert Into #YourTable values
('31-12-2018')
,('01-01-2019')
,('02-01-2019')
Set DateFormat DMY
Select AsDate = try_convert(date,SomeCol)
From #YourTable
Returns
AsDate
2018-12-31
2019-01-01
2019-01-02

Converting an irregular varchar to datetime in sql server

I'm working on revamping a database right now, and all the datetime's are stored in varchar's formatted like so: DDMonYY hhmm (ex. 13Mar99 2032).
I don't have a lot of experience with SQL, as I only just finished my first year of college so I'm having a really hard time trying to get this to work so any help would be appreciated.
All you should need to do for your particular string is to get a colon in between the hour and minute values. Something like:
SELECT CAST(STUFF('13Mar99 2032', LEN('13Mar99 2032') - 1, 0, ':') AS datetime)
should work.
You can pick a datetime format and then shift parts of the string to match it. For example, format 7 is:
select convert(varchar(25), getdate(), 7)
-->
'Jun 23, 14'
So you can use substring to transform your string:
declare #orig varchar(30) = '13Mar99 2032'
declare #conv varchar(30)
select #conv = substring(#orig, 3, 3) + ' ' + substring(#orig, 1, 2) + ', ' +
substring(#orig, 6, 2) + ' ' + substring(#orig, 9, 2) + ':' + substring(#orig, 11, 2)
select #conv
, convert(datetime, #conv, 7)
-->
'Mar 13, 99 20:32' 1999-03-13 20:32:00.000

SQL date conversion year/datepart to datetime

I am trying to convert from "tick" date format to a datetime format.
Example:
0000113326 to 2013-11-22 00:00:00.000
I know how to go the opposite way:
SELECT '00001' + RIGHT(CAST(YEAR(StartDate) AS varCHAR(4)), 2) + RIGHT('000' + CAST(Datepart(dy, StartDate) AS VARCHAR(3)), 3)
FROM table
I just need to reverse engineer it.
Any ideas?
Something like this?
DECLARE #tick varchar(20) = '0000113326'
SELECT dateadd(d, cast(right(#tick, 3) as int) - 1, '20' + substring(#tick, 6, 2) + '0101')