Related
I have a field named SECURED that has dates listed as 123120, 040320 which is actually 12/31/20 or 4/03/20.
I was able to convert the date in the SELECT area with:
SELECT LEFT(SECURED, 2) + '/' + replace(replace(SECURED, LEFT(SECURED, 2), ''),
RIGHT(SECURED, 2), '') + '/' + RIGHT(SECURED, 2) as 'Modified SECURED as Date'
WHERE CONVERT(date, SECURED, 101)
BETWEEN CONVERT(date, getdate() - 30, 101)
AND CONVERT(date, getdate(), 101)
How can I pull in information from the SECURED column with a date of 30 days ago?
It doesn't work and still sees a date as a number.
You can use datefromparts() to convert your string to a date:
datefromparts(
concat('20', substring(secured, 5, 2)),
substring(secured, 1, 2),
substring(secured, 3, 2)
)
Then you can check it against a given interval:
datefromparts(
concat('20', substring(secured, 5, 2)),
substring(secured, 1, 2),
substring(secured, 3, 2)
) between dateadd(day -30, cast(getdate() as date)) and cast(getdate() as date)
If secured is a string, you can do a little manipulation and a simple cast():
select convert(date, concat('20', right(secured, 2), left(secured, 4))
You might find it convenient to actually create a computed column so this is always available:
alter table t add secured_date as (try_convert(date, concat('20', right(secured, 2), left(secured, 4))
You can even persist the column and create an index, so your queries are more efficient.
There're many ways to convert a 6 digits INT to DATE:
You can do a convertion using LTRIM and CAST like this:
SELECT CAST(RIGHT(LTRIM(123120),2) + LEFT(LTRIM(123120),4) AS DATE)
Using LTRIM with SUBSTRING:
SELECT CAST(SUBSTRING(LTRIM(040320), 5, 2) + SUBSTRING(LTRIM(040320), 1, 4) AS DATE)
Using CONVERT:
SELECT CAST((RIGHT(CONVERT(VARCHAR(6), 123120),2) +
LEFT(CONVERT(VARCHAR(6), 123120),4)) AS DATE)
Or using CONVERT with SUBSTRING:
SELECT CAST(SUBSTRING(CONVERT(VARCHAR(6), 040320), 5, 2) +
SUBSTRING(CONVERT(VARCHAR(6), 040320), 1, 4) AS DATE)
Using STR:
SELECT CAST(RIGHT(STR(123120, 6) ,2) + LEFT(STR(123120, 6) ,4) AS DATE)
Or using STR with SUBSTRING:
SELECT CAST(SUBSTRING(STR(040320, 6), 5, 2) + SUBSTRING(STR(040320, 6), 1, 4) AS DATE)
This casting will format the date as expected but your dates need be
in format mmddyy
Standard EUA (style 10) DATE format (mm-dd-yy) without century (yy)
Edit after comments:
What's the table name of this query?
What's the SECURED field datatype? INT? VARCHAR?
You need convert a date and compare between last 30 days and today?
The query below resolve your problem? (change TABLE_NAME to your table name)
SELECT LEFT(SECURED, 2) + '/' + replace(replace(SECURED, LEFT(SECURED, 2), ''),
RIGHT(SECURED, 2), '') + '/' + RIGHT(SECURED, 2) as 'Modified SECURED as Date'
FROM TABLE_NAME
WHERE CAST(RIGHT(LTRIM(SECURED), 2) + LEFT(LTRIM(SECURED), 4) AS DATE)
BETWEEN GETDATE() - 30 AND GETDATE()
I'm getting this type of data in DateandTime Column in SQl.
1803301611.1803301611
Format is yymmddhhmm.yymmddhhmm and I have to convert this data in a date format.
The DateandTime Column date type is Varchar(5)
I don't think the format of your time string can be directly converted by SQL Server. But, we can try to piece together into a format which can be. This is the closest I could come, and it required prepending a 20 in front of the year to make a full 4 digit century:
SELECT
col AS input,
CONVERT(datetime, '20' + SUBSTRING(col, 1, 2) + '-' + SUBSTRING(col, 3, 2) + '-' +
SUBSTRING(col, 5, 2) + ' ' + SUBSTRING(col, 7, 2) + ':' +
SUBSTRING(col, 9, 2), 120) AS output
FROM yourTable;
Demo
We ideally should have been able to use mask 20 without the century, but I could not get it to work.
You can do :
select *, cast(concat(cast(left(col, 6) as date), ' ',stuff(right(col, 4), 3, 0, ':')
) as datetime
) as newdatetime
from table t;
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
I have a list of months that get populated into my DB. These months then get populated into a drop down list for a web Application. The client wants the current month to be the default option in the drop down list. However, the current month's data is not always available (Or ActiveFlag=Y in the database). So in that case, the client wants the default to be the first month of the year instead.
So I am testing that the drop down list and the DB table match using Selenium automation with C#. I have an SQL query that returns the Top 1 sorted in Descending order (This works to return the last active month in the year, because BroadcastMonthofYearNbr contains integers 1 through 12 month numbers):
SELECT top 1 CONCAT(RTRIM(left(M.Name, CHARINDEX(',',M.Name)-1)), ' (', STUFF(REPLACE('/'+CONVERT( VARCHAR(10), M.StartDate, 101), '/0', '/'), 1, 1, ''), '-', STUFF(REPLACE('/'+CONVERT(VARCHAR(10), M.EndDate, 101), '/0', '/'), 1, 1, ''), ')')
FROM [AudienceProjections].[dbo].[BroadcastCalendarQuarterMonthMap] QMP,
AudienceProjections.dbo.BroadcastCalendarYear Y,
AudienceProjections.dbo.BroadcastCalendarMonth M,
AudienceProjections.dbo.BroadcastCalendarQuarter Q
WHERE y.BroadcastCalendarYearUuid = q.BroadcastCalendarYearUuid
AND q.BroadcastCalendarQuarterUuid = qmp.BroadcastCalendarQuarterUuid
AND qmp.BroadcastCalendarMonthUuid = m.BroadcastCalendarMonthUuid
AND M.ActiveStatus = 'ACTIVE'
AND y.ActiveStatus = 'ACTIVE'
AND q.BroadcastQuarterType = 'STANDARD'
AND y.BroadcastCalendarYear = YEAR(GETDATE())
ORDER BY qmp.BroadcastMonthofYearNbr DESC
The query above returns this:
No Column Name
April (3/28/2016-4/24/2016)
The current month for when I am posting this question is May 5th. Notice that the above query result returns April, not May. This is because May data has not yet been imported into the DB (See below table for distinction of the data being there or not. I.e Active versus Inactive). So my query wont work in this case. I would now need a CASE THEN ELSE, or an IF EXISTS type of function, to return January if this situation occurs
Here is the Month table that you can see have May as INACTIVE:
Name StartDate EndDate ActiveStatus
January, 2016 2015-12-28 2016-01-31 ACTIVE
February, 2016 2016-02-01 2016-02-28 ACTIVE
March, 2016 2016-02-29 2016-03-27 ACTIVE
April, 2016 2016-03-28 2016-04-24 ACTIVE
May, 2016 2016-04-25 2016-05-29 INACTIVE
NOTE: I forgot about the situation of the current date being January, and if January isnt there, then the Year wouldnt be there yet either. So the condition in the query would need to take Year into account. The year table (BroadcastCalendarYear) also has an ActiveStatus column which can be used.
So if the year is also inactive, then return me a string that says "No data in DB for Year".
I assume you will be able to adapt the following to your specific schema but here is an example as order by that would work. Note you may not need and should remove some of the where statements hard to know without knowing the dataset.
Also what month should be returned if it is January of the current year and nothing is active? You may have to adapt the order by depending on that answer.
SELECT TOP 1 *
FROM
#Months
WHERE
ActiveStates = 'ACTIVE'
AND ????
ORDER BY
CASE WHEN YEAR(GETDATE()) = YearInt THEN 9999 ELSE YearInt END DESC -- Assumes you want to order by most recent to oldest and that youcould potentially have a future year loaded in the table. Othwerwuse simply use YearInt DESC
,CASE WHEN MONTH(GETDATE()) = MonthInt THEN 0 ELSE 1 END --Puts precedence on current month
,MonthInt DESC
I hope this helps.
IF OBJECT_ID(N'tempdb..#Month') IS NOT NULL
DROP TABLE #Month
CREATE TABLE #Month
(Year INT, Month VARCHAR(3), ActiveStatus CHAR(1))
INSERT INTO #Month(Year, Month, ActiveStatus)
VALUES(2016,'Jan','A')
,(2016,'Feb','A')
,(2016,'Mar','A')
,(2016,'Apr','A')
,(2016,'May','I')
;WITH x AS
(
SELECT
*,EOMONTH(CONCAT(Year,'-',Month,'-','01')) As Date
FROM #Month
)
SELECT
*
FROM X
WHERE
-- current month is active or current month is inactive then first month of the current year
Year = YEAR(GETDATE()) AND
(DATEPART(MONTH,Date)=DATEPART(MONTH,GETDATE()) AND ActiveStatus='A') OR (1=DATEPART(MONTH,Date) AND EXISTS(SELECT 1 FROM x WHERE DATEPART(MONTH,Date)=DATEPART(MONTH,GETDATE()) AND ActiveStatus='I'))
I figured it out with a long and convoluted solution, but it works.
SELECT CASE WHEN t.month = (SELECT left(M.Name, CHARINDEX(',',M.Name)-1) FROM [AudienceProjections].[dbo].[BroadcastCalendarMonth] M
WHERE StartDate <= GETDATE() AND EndDate >= GETDATE() ) THEN CONCAT(RTRIM(left(t.Name, CHARINDEX(',',t.Name)-1)), ' (', STUFF(REPLACE('/'+CONVERT( VARCHAR(10), t.StartDate, 101), '/0', '/'), 1, 1, ''), '-', STUFF(REPLACE('/'+CONVERT(VARCHAR(10), t.EndDate, 101), '/0', '/'), 1, 1, ''), ')') ELSE ( SELECT CONCAT(RTRIM(left(M.Name, CHARINDEX(',',M.Name)-1)), ' (', STUFF(REPLACE('/'+CONVERT( VARCHAR(10), M.StartDate, 101), '/0', '/'), 1, 1, ''), '-', STUFF(REPLACE('/'+CONVERT(VARCHAR(10), M.EndDate, 101), '/0', '/'), 1, 1, ''), ')') FROM AudienceProjections.dbo.BroadcastCalendarMonth M WHERE NAME = CONCAT( DATENAME(month,DATEADD(yy, DATEDIFF(yy,0,getdate()), 0)), ', ', DATENAME(year,DATEADD(yy, DATEDIFF(yy,0,getdate()), 0)) ) ) END month FROM (
SELECT top 1 left(M.Name, CHARINDEX(',',M.Name)-1) AS month,
M.Name, M.StartDate, M.EndDate
FROM [AudienceProjections].[dbo].[BroadcastCalendarQuarterMonthMap] QMP,
AudienceProjections.dbo.BroadcastCalendarYear Y,
AudienceProjections.dbo.BroadcastCalendarMonth M,
AudienceProjections.dbo.BroadcastCalendarQuarter Q
WHERE y.BroadcastCalendarYearUuid = q.BroadcastCalendarYearUuid
AND q.BroadcastCalendarQuarterUuid = qmp.BroadcastCalendarQuarterUuid
AND qmp.BroadcastCalendarMonthUuid = m.BroadcastCalendarMonthUuid
AND M.ActiveStatus = 'ACTIVE'
AND q.BroadcastQuarterType = 'STANDARD'
AND y.ActiveStatus = 'ACTIVE'
AND y.BroadcastCalendarYear = YEAR(GETDATE())
ORDER BY qmp.BroadcastMonthofYearNbr DESC) t
Using IF EXISTS, ELSE IF EXISTS, ELSE accomplishes all 3 conditions:
IF EXISTS (
SELECT CONCAT(q.DisplayName, ' (', STUFF(REPLACE('/'+CONVERT( VARCHAR(10), q.StartDate, 101), '/0', '/'), 1, 1, ''), '-', STUFF(REPLACE('/'+CONVERT(VARCHAR(10), q.EndDate, 101), '/0', '/'), 1, 1, ''), ')')
FROM AudienceProjections.dbo.BroadcastCalendarYear Y,
AudienceProjections.dbo.BroadcastCalendarQuarter Q
WHERE y.BroadcastCalendarYearUuid = q.BroadcastCalendarYearUuid
AND q.BroadcastQuarterType = 'STANDARD'
AND y.ActiveStatus = 'ACTIVE'
AND q.ActiveStatus = 'ACTIVE'
AND y.BroadcastCalendarYear = YEAR(GETDATE())
AND Q.StartDate <= GETDATE()
and Q.EndDate >= GETDATE())
SELECT CONCAT(q.DisplayName, ' (', STUFF(REPLACE('/'+CONVERT( VARCHAR(10), q.StartDate, 101), '/0', '/'), 1, 1, ''), '-', STUFF(REPLACE('/'+CONVERT(VARCHAR(10), q.EndDate, 101), '/0', '/'), 1, 1, ''), ')')
FROM AudienceProjections.dbo.BroadcastCalendarYear Y,
AudienceProjections.dbo.BroadcastCalendarQuarter Q
WHERE y.BroadcastCalendarYearUuid = q.BroadcastCalendarYearUuid
AND q.BroadcastQuarterType = 'STANDARD'
AND y.ActiveStatus = 'ACTIVE'
AND q.ActiveStatus = 'ACTIVE'
AND y.BroadcastCalendarYear = YEAR(GETDATE())
AND Q.StartDate <= GETDATE()
and Q.EndDate >= GETDATE() ELSE IF EXISTS (
SELECT TOP 1 CONCAT(q.DisplayName, ' (', STUFF(REPLACE('/'+CONVERT( VARCHAR(10), q.StartDate, 101), '/0', '/'), 1, 1, ''), '-', STUFF(REPLACE('/'+CONVERT(VARCHAR(10), q.EndDate, 101), '/0', '/'), 1, 1, ''), ')')
FROM [AudienceProjections].[dbo].[BroadcastCalendarQuarterMonthMap] QMP,
AudienceProjections.dbo.BroadcastCalendarYear Y,
AudienceProjections.dbo.BroadcastCalendarQuarter Q
WHERE y.BroadcastCalendarYearUuid = q.BroadcastCalendarYearUuid
AND q.BroadcastCalendarQuarterUuid = qmp.BroadcastCalendarQuarterUuid
AND q.BroadcastQuarterType = 'STANDARD'
AND y.ActiveStatus = 'ACTIVE'
AND q.ActiveStatus = 'ACTIVE'
AND y.BroadcastCalendarYear = YEAR(GETDATE()) ORDER BY qmp.BroadcastMonthofYearNbr ASC ) SELECT TOP 1 CONCAT(q.DisplayName, ' (', STUFF(REPLACE('/'+CONVERT( VARCHAR(10), q.StartDate, 101), '/0', '/'), 1, 1, ''), '-', STUFF(REPLACE('/'+CONVERT(VARCHAR(10), q.EndDate, 101), '/0', '/'), 1, 1, ''), ')')
FROM [AudienceProjections].[dbo].[BroadcastCalendarQuarterMonthMap] QMP,
AudienceProjections.dbo.BroadcastCalendarYear Y,
AudienceProjections.dbo.BroadcastCalendarQuarter Q
WHERE y.BroadcastCalendarYearUuid = q.BroadcastCalendarYearUuid
AND q.BroadcastCalendarQuarterUuid = qmp.BroadcastCalendarQuarterUuid
AND q.BroadcastQuarterType = 'STANDARD'
AND y.ActiveStatus = 'ACTIVE'
AND q.ActiveStatus = 'ACTIVE'
AND y.BroadcastCalendarYear = YEAR(GETDATE())
ORDER BY qmp.BroadcastMonthofYearNbr ASC; ELSE SELECT 'No Active quarters are in the database for the current year yet';
Good Day
I am working of a existing SQL Server Database. What the developers did is to keep the Date and time separate. The Date is in DateTime format (what I want) but the time is incorrect. if it is 14:30 it shows as 1430 when its 09:25 shows as 925. I am trying tyo combine the date and time to have a Date Time view for an program I am writing on top of this database.
I have created the date as a normal date like this:
CASE
WHEN LEN(T0.BeginTime) = 3 THEN '0' + LEFT(T0.BeginTime, 1) + ':' + RIGHT(T0.BeginTime, 2)
ELSE LEFT(T0.BeginTime, 2) + ':' + RIGHT(T0.BeginTime, 2)
END AS 'NEW Start Time'`
The date now looks like it's the correct format but when I want to combine the date and time I get VARCHAR to DateTime error.
How can I fix this?
This is the error:
The conversion of a varchar data type to a datetime data type resulted in an out-of-range value (ONLY RAN 804 RECORDS)
Thanks
This should do the trick, Hope it helps.
DECLARE #DateTime TABLE (
DateWithTime DATE,
BeginTime INT);
INSERT INTO #DateTime
VALUES ('2014-08-04', '1525'),
('2014-08-04', '525'),
('2014-08-04', '15'),
('2014-08-04', '5'),
('2014-08-04', '0'),
('2014-08-04', '90')
;WITH cte_BeginTimeFix
AS (
SELECT
CONVERT(VARCHAR(10), DateWithTime, 120) AS DateWithTime,
RIGHT('0000' + CAST(BeginTime AS VARCHAR(4)), 4) AS BeginTime
FROM #DateTime
)
, cte_DateString
AS (
SELECT DateWithTime,
BeginTime,
DateWithTime + ' ' + STUFF(STUFF('00:00:00.000', 4, 2, RIGHT(BeginTime, 2)), 1, 2, LEFT(BeginTime, 2)) AS DateTimeStr
FROM cte_BeginTimeFix
)
SELECT DateWithTime,
BeginTime,
CASE
WHEN ISDATE(DateTimeStr) = 1 THEN CAST(DateTimeStr AS DATETIME)
ELSE NULL
END AS DateTimeStr
FROM cte_DateString
A different approach is to convert the time column in minutes and add it to the date
DATEADD(minute, T0.BeginTime / 100 * 60 + T0.BeginTime % 100
, CONVERT(VARCHAR, T0.BeginDate, 112))
with that the length of the time column doesn't matter
This should work:
CONVERT
(
DATETIME,
CONVERT(VARCHAR,T0.Date,112) +
' ' +
CASE
WHEN ISNULL(T0.BeginTime,'0') = '0'
THEN '00:00'
ELSE
RIGHT
(
'00' + LEFT(T0.BeginTime,LEN(T0.BeginTime) - 3),
2
) +
':' +
RIGHT(T0.BeginTime,2)
END
)