Computed column - sql-server-2005

In current table I have a column that holds the date field in ddmmyyyy format and it is of type varchar(8). The column has some string value also. I want to create a computed column that will hold the value in DateTime format if the value in source column is valid date time.

Assuming your varchar(8) column is dateString :
Cast([dateString] as datetime)

SQL Server prefers dates in the format of yyyymmdd so there will be some string manipulation involved to format your data like this. We should also use the IsDate function to make sure we have a valid date.
So:
Cast(Case When IsDate(Right(#Data, 4)
+ SubString(#Data, 3, 2)
+ Left(#Data, 2)) = 1
Then Right(#Data, 4)
+ SubString(#Data, 3, 2)
+ Left(#Data, 2) End As DateTime)
Notice that this code should correctly handle invalid dates contained within your varchar column. If a date is invalid, this code will return NULL.

try parsing your varchar into dd/mm/yyyy before attempting the cast:
cast(substring([datestring],1,2) + '/' +
substring([datestring],3,2) + '/' +
substring([datestring],5,4) as datetime)

Related

Change the numeric format into 'AM/PM' format in CONCAT / MAX (sql)

I need to change the numeric format into 'AM/PM' format in CONCAT function (I use SSMS v 18.5.1)
Here is my formula. RCLDTE - is a date and RCLTIM is time. I basically need to leave RCLDTE as it is and change the format of RCLTIM from numeric to date and convert to AM/PM format.
How the column looks right now
Format of RCLTIM - numeric
CONCAT(c.RCLDTE, ' & ', MAX(c.RCLTIM)) AS 'Date & Time',
When I tried to use CONVERT function as I tend to use, it raised an error.
CONCAT(c.RCLDTE, ' & ', CONVERT(varchar(15),CAST( MAX(c.RCLTIM) AS TIME),100))
Error
Explicit conversion from data type numeric to time is not allowed.
The number for the date can be concatenated to the number for the time stuffed with colons. So that it can be converted to a DATETIME.
And by using FORMAT the DATETIME can be put in a specific format.
(But use CONVERT if it has the format.)
Test snippet
declare #test table (
ID INT IDENTITY PRIMARY KEY,
RCLDTE int,
RCLTIM int
);
insert into #test (RCLDTE, RCLTIM) values
(20220119, 215250)
, (20220304, 070809)
;
select
FORMAT(TRY_CAST(CONCAT(c.RCLDTE, ' ', STUFF(STUFF(FORMAT(MAX(c.RCLTIM),'000000'),5,0,':'),3,0,':')) AS DATETIME)
, 'd/M/yyyy hh:mm:ss tt') AS [Date & Time]
from #test c
group by RCLDTE;
Date & Time
19/1/2022 09:52:50 PM
4/3/2022 07:08:09 AM
Test on db<>fiddle here
What you're attempting to do is very fragile, but I presume your source system gives you few options.
Converting like this has potential problems with DST & the language in use at the time of running.
Your question lost some of the detail regarding formats, so I can't see the time type you are using, but it looks like a decimal again.
Essentially, you need to put the the numerics in a string and then into datetime columns, but to get there you have to match a string conversion format the sqlserver.
Fortunately you are not far off the us format default.
Something like this will get you a date field, you can then amend the output format if you really need 12hr rather than 24hr.
SET LANGUAGE us_english
DECLARE #rcldte NUMERIC, #rcltim numeric
SET #rcldte=20220119
SET #rcltim = 015250
SELECT
CONVERT(DATETIME, CAST (#rcldte AS VARCHAR)+ ' ' +
LEFT( left('000000', 6-LEN(CAST ( #rcltim AS VARCHAR)))+CAST ( #rcltim AS VARCHAR),2)
+ ':' + substring( left('000000', 6-LEN(CAST ( #rcltim AS VARCHAR)))+CAST ( #rcltim AS VARCHAR),3,2)
+ ':' + RIGHT( left('000000', 6-LEN(CAST ( #rcltim AS VARCHAR)))+CAST ( #rcltim AS VARCHAR),2))
Which will give you:
(No column name)
2022-01-19 01:52:50.000
It's rather ugly though.
If you can guarantee the hours are zero padded then you could remove the complexity associated with that.
And if you're really going to use it then split into proper UDFs...
DECLARE #RCLDTE CHAR(8) = '20220119';
DECLARE #RCLTIM CHAR(6) = '215250';
select CONVERT(VARCHAR(21), (cast(#RCLDTE as DATETIME) + cast(substring(#RCLTIM,1,2)+':'+substring(#RCLTIM,3,2)+':'+substring(#RCLTIM,5,2) as DATEtime) ), 22);
output: 01/19/22 9:52:60 PM
For different formats of the DATETIME, see the docs of the CONVERT function:
https://learn.microsoft.com/en-us/sql/t-sql/functions/cast-and-convert-transact-sql?view=sql-server-ver15
NOTE: When specifying another format the value 21 in VARCHAR(21) might need a change...

Convert nvarchar date (DD/MM/YYYY) to Date Period (YYYY_MM)

I am trying to convert this into a period format, so e.g. 2018_05 (YYYY_MM). currently the data is in DD/MM/YYYY format.
I tried a cast code but it returns me YYYY_DD.
SELECT
CASE WHEN RESERVED_FIELD_4 IS NULL THEN NULL
ELSE cast(year(RESERVED_FIELD_4) as Nvarchar (4))
+'_'+right('00'+cast(month(RESERVED_FIELD_4) as Nvarchar (2)),2)
END AS [DATAFEED_PERIOD]
I expect/want to see YYYY_MM.
Assuming RESERVED_FIELD_4 is a string type (char/nchar/varchar/nvarchar) the simplest solution would be to use substring:
CASE
WHEN RESERVED_FIELD_4 IS NULL THEN NULL
ELSE SUBSTRING(RESERVED_FIELD_4, 7, 4) + '_'+ SUBSTRING(RESERVED_FIELD_4, 4, 2)
END AS [DATAFEED_PERIOD]
If it's a date/datetime/datetime2 data type, the simplest solution would be to use format:
FORMAT(RESERVED_FIELD_4, 'yyyy_MM')
But for better performance you can use convert and stuff:
SELECT STUFF(CONVERT(char(6), RESERVED_FIELD_4, 112), 5, 0, '_')
In case your format is actually d/m/y the simplest option is to convert to date and than back to string:
SELECT STUFF(CONVERT(char(6), CONVERT(Date, RESERVED_FIELD_4, 103), 112), 5, 0, '_')
This is the common problem of storing a date with a VARCHAR column. You are guessing that the stored pattern is DD/MM/YYYY but the SQL engine doesn't know that and is currently assuming the MM/DD/YYYY pattern.
Please check these results:
-- MM/DD/YYYY
SELECT
DAY ('05/01/2019'), -- 1
MONTH('05/01/2019') -- 5
-- DD/MM/YYYY
SELECT
DAY ('25/05/2019'), -- Conversion failed when converting date and/or time from character string
MONTH('25/05/2019') -- Conversion failed when converting date and/or time from character string.
To display what you want correctly use string functions:
SELECT
RIGHT(RESERVED_FIELD_4, 4) + '_' + SUBSTRING(RESERVED_FIELD_4, 4, 2)
But you should actually fix the values on your VARCHAR column, cast them to DATE and store the values as DATE.
ALTER TABLE YourTable ADD ReservedField4Date DATE
UPDATE YourTable SET
ReservedField4Date = CONVERT(DATE,
RIGHT(RESERVED_FIELD_4, 4) -- Year
+ '-' + SUBSTRING(RESERVED_FIELD_4, 4, 2) -- Month
+ '-' + LEFT(RESERVED_FIELD_4, 2)) -- Day
ALTER TABLE YourTable DROP COLUMN RESERVED_FIELD_4
EXEC sp_rename 'SchemaName.YourTable.ReservedField4Date', 'RESERVED_FIELD_4', 'COLUMN'
Beware that changing the column type might affect other queries that assume this is a VARCHAR column.
If your data is in DD/MM/YYYY format, then it is being stored as a string. Hence, string functions come to mind:
select right(RESERVED_FIELD_4) + '_' + substrint(RESERVED_FIELD_4, 4, 2)
In SQL-SERVER you can use 'format'
format(dy,#your_date) as day_of_year
month(#your_date) as month
Try this:
Select concat(month(#your_date),'_'year(#your_date)) as your_period
this is a reference
Why not just do conversations ? :
SELECT REPLACE(CONVERT(VARCHAR(7), CONVERT(date, RESERVED_FIELD_4, 101), 102), '.', '_')
This assumes RESERVED_FIELD_4 is date type.

How to split dash-separated values in SQL Server

I have a date saved in an nvarchar type and I want to split the day, month and year into separate nvarchar variables (that means three variables). The date looks as follows: exposure_date ='2018-12-04' and the format is yyyy-dd-mm
any help please?
My whole project is stuck on this.
The "correct" answer here is to fix your datatype. When storing data always choose an appropriate data type for the data you're storing. For a date (with no time part) then the correct datatype is date. if you're storing numerical data, then use a numerical datatype, such as int or decimal. (n)varchar is not a one size fits all datatype and using it to store data that has a data type designed for it is almost always a bad choice. I'm storing the data as an (n)varchar because I need it in a specific format is never an excuse; have your presentation layer handle to display format, not your RDBMS.
The first step, therefore would be to change your string representation yyyy-dd-MM of a date to the ISO format yyyyMMdd by doing:
UPDATE YourTable
SET exposure_date = LEFT(exposure_date,4) + RIGHT(exposure_date,2) + SUBSTRING(exposure_date,6,2);
Now you have a unambiguous representation, you can change the data type of your column without concerns of incorrect implicit casts or error:
ALTER YourTable ALTER COLUMN exposure_date date;
Then, finally, you can treat your data as what it is, a date, and use the DATEPART function:
SELECT DATEPART(YEAR,exposure_date) AS Exposure_Year,
DATEPART(MONTH,exposure_date) AS Exposure_Month,
DATEPART(DAY,exposure_date) AS Exposure_Day
FROM YourTable;
You can also try the following
Declare #myDate date
select #myDate= Cast(substring('2011-29-12', 1, 4)
+ '-' + substring('2011-29-12', 9, 2)
+ '-' + substring('2011-29-12', 6, 2)
as Date) --YYYY-MM-DD
Select #myDate as DateTime,
datename(day,#myDate) as Date,
month(#myDate) as Month,
datename(year,#myDate) as Year,
Datename(weekday,#myDate) as DayName
The output is as shown below
DateTime Date Month Year DayName
--------------------------------------------
2011-29-12 29 12 2011 Thursday
You can find the live demo here
You can try below -
select concat(cast(year(cast('2018-12-04' as date)) as varchar(4)),'-',
cast(month(cast('2018-12-04' as date)) as varchar(2)), '-',
cast(day(cast('2018-12-04' as date)) as varchar(2)))
from tablename
If you have fixed format, then you could use this simple query with substring method:
select substring(dt, 1, 4) + '-' +
substring(dt, 9, 2) + '-' +
substring(dt, 6, 2) [YYYY-MM-DD]
from (values ('2018-31-12')) tbl(dt)
Let's go directly to the main issue, which is you are using the wrong datatype to store dates, you should store them as DATE, the datatypes are there for a reason and you need to choose a proper one for your column.
So, you need to ALTER your table and change the column datatype to DATE instead of NVARCHAR datatype.
ALTER <Table Name Here>
ALTER COLUMN <Column Name Here> DATE;
Then all things will easy, you just run the following query to get the desired output
SELECT YEAR(<Column Name Here>) TheYear,
MONTH(<Column Name Here>) TheMonth,
DAY(<Column Name Here>) TheDay
FROM <Table Name Here>
Which is the right and the best solution.
You can also (if you are not going to alter your table) do as
CREATE TABLE Dates(
StrDate NVARCHAR(10)
);
INSERT INTO Dates VALUES
(N'2018-12-04'),
(N'Invalid');
SELECT LEFT(StrDate, 4) StrYear,
SUBSTRING(StrDate, 6, 2) StrMonth,
RIGHT(StrDate, 2) StrDay
FROM Dates;
OR
SELECT YEAR(StrDate) StrYear,
MONTH(StrDate) StrMonth,
DAY(StrDate) StrDay
FROM (
SELECT TRY_CAST(StrDate AS DATE) StrDate
FROM Dates
)T

Function to evaluate valid and invalid dates

I am using SQL Server 2008
I receive data in a couple of formats. Dates are varchar(10)
For example:
1> 951116 = YYMMDD
2> 122487 = MMDDYY
There exists rows with blank values or some rows have some text in it.
I want to check if it is a date and convert it, else it can be null.
I have been using the following code but it only enables me to convert the date as in the 1st example and throws an error in the second one.
create view v2 as
SELECT name
,CASE WHEN LEN(DOB) < 6 THEN '' ELSE CONVERT(VARCHAR,
CAST(CAST('19' + SUBSTRING(DOB, 5, 2) + SUBSTRING(DOB, 1, 2) + SUBSTRING(DOB, 3, 2) AS VARCHAR(10)) AS DATE), 110) END AS OWNR_DOB
FROM customer
I want to write a function and get it to YYYYMMDD format.
A simple function just to convert the YYMMDD format to YYYYMMDD and treat the other values as invalid or null can be a start too.
Any help is appreciated.

SQL Server: How to concatenate string constant with date?

select packageid,status+' Date : '+UpdatedOn from [Shipment_Package]
The below error is appeared when executing the above code in sql server. The type of UpdatedOn is DateTime and status is a varchar. We wanted to concatenate the status, Date and UpdatedOn.
error:
Conversion failed when converting date and/or time from character
string.
You need to convert UpdatedOn to varchar something like this:
select packageid, status + ' Date : ' + CAST(UpdatedOn AS VARCHAR(10))
from [Shipment_Package];
You might also need to use CONVERT if you want to format the datetime in a specific format.
To achive what you need, you would need to CAST the Date?
Example would be;
Your current, incorrect code:
select packageid,status+' Date : '+UpdatedOn from [Shipment_Package]
Suggested solution:
select packageid,status + ' Date : ' + CAST(UpdatedOn AS VARCHAR(20))
from [Shipment_Package]
MSDN article for CAST / CONVERT
Hope this helps.
To account for null values, try this:
select packageid,
'Status: ' + isnull(status, '(null)') + ', Date : '
+ case when UpdatedOn is null then '(null)' else convert(varchar(20), UpdatedOn, 104) end as status_text
from [Shipment_Package]
Convert Datetime column into varchar for sql Server you can use below code
select packageid,status+' Date : '+CONVERT(VARCHAR,UpdatedOn,120) from [Shipment_Package]
120 code will convert your date into this format : 2020-06-12 15:09:00
other format you can use from this link