T-sql: Case show date or convert date to nvarchar - tsql

I want to use a case statement where my logic determines a date. If the value returned is a null value I instead want to display 'none' instead of a null value.
See code below.
CASE WHEN DATEDIFF(d, vso.pod_ata, ISNULL(cncr.cntr_date3, GETUTCDATE())) - 14 > 0 THEN vso.pod_ata + 14
ELSE CONVERT(NVARCHAR(10), 'none')
END AS 'start_dem',
SQL SERVER was complaining about conversion so I tried converting it to nvarchar but thats not working. Does anyone know a good solution for this?

You should convert the date, not the string.
CASE WHEN DATEDIFF(d, vso.pod_ata, ISNULL(cncr.cntr_date3, GETUTCDATE())) > 14 THEN convert(VARCHAR(10), dateadd(day, 14, vso.pod_ata), 120)
ELSE 'none'
END AS 'start_dem',

SQL, to my knowledge, does not allow mixed datatypes in the same column. Convert the vso.pod_ata + 14 to an NVARCHAR as well.
CASE WHEN DATEDIFF(d, vso.pod_ata, ISNULL(cncr.cntr_date3, GETUTCDATE())) - 14 > 0 THEN CONVERT(NVARCHAR(50), vso.pod_ata + 14)
ELSE CONVERT(NVARCHAR(50), 'none')
END AS 'start_dem',

Related

How to change default value of date filter in metabase?

I am trying to write dynamic sql query in metabase-
I added date filter like that (using snowflake for query):
select * from my_table where date > {{date_filter}}
after that I needed to set default value of yesterday to date_filter, so I write this:
select * from my_table where date > [[{{date_filter}} #]]dateadd(DAY, -1, GETDATE())
and it worked, when I ran this query- I got the right output.
BUT- when I changed the date in the calendar that metabase provided for date types- I got this error:
SQL compilation error: syntax error line 1 at position 142 unexpected '#D'. syntax error line 1 at position 156 unexpected '-'. syntax error line 1 at position 172 unexpected '('.
How can I change date_filter default value without getting this error?
finally found a workaround that solve the problem.
in UI settings, define date_filter as REQUIRED and assign static default value- for example 01.01.2015 if my table contains data starting of 2016.
in sql query- I wrote that:
select * from my_table where date > case when year({{date_filter}}) = 2015 then dateadd(DAY, -1, GETDATE()) else {{date_filter}} end
which means:
if I won't select any date in date_filter calender- date_filter year value will be 2015 (as I defined date_filter = 01.01.2015) so I will compare DATE against dateadd(DAY, -1, GETDATE()).
but if I WILL select value in date_filter calender, then year(date_filter) will be different than 2015 (as I said, I won't choose date before 2016 because I have no data before 2016 in my table) so I will compare DATE against {{date_filter}} value which I just selected.

Casting DATETIME on concatenated date and time

I'm trying to concatenate a column's date to a fixed time of the day and then CAST the whole thing as DATETIME.
The fixed time is 5:30am.
The date column I'm using needs to be adjusted as it shows the end date/time of when something ran; I want to use the start date/time.
The start date/time time is not available as its own column, but I have another column that has the duration the process took in seconds, so I can use DATEADD to roll the end date/time back to the start date/time.
Here's the full statement:
CAST(CONVERT(VARCHAR(10), DATEADD(ss,-ConfTask.[LastExecutedDuration], ConfTask.[LastExecutedDate]), 103) + ' ' + '05:30' as DATETIME)
Here's the error message I'm receiving:
The conversion of a varchar data type to a datetime data type resulted
in an out-of-range value.
I've tried testing these statements to investigate the issue, but they all run OK on their own:
CAST(CONVERT(VARCHAR(10), GETDATE(), 103) + ' ' + '05:30' as DATETIME)
CAST('2017-03-02' + ' ' + '05:30' as DATETIME)
DATEADD(ss,-ConfTask.[LastExecutedDuration], ConfTask.[LastExecutedDate])
I'm a bit stuck on how to get round this issue. Any help would be much appreciated.
Clearly, you must have some unexpected values in the column.
I would suggest finding them using a query such as this:
SELECT LastExecutedDuration, LastExecutedDate
FROM ConfTask
WHERE TRY_CONVERT(datetime,
CONVERT(VARCHAR(10),
DATEADD(second,
-ConfTask.[LastExecutedDuration],
ConfTask.[LastExecutedDate]
)
103
) + ' ' + '05:30')
)
You can also simplify the logic, by just using date functions:
select dateadd(minute,
5 * 60 + 30,
convert(datetime,
convert(date,
dateadd(second,
- ConfTask.LastExecutedDuration
ConfTask.LastExecutedDate
)
)
)
)
This worked:
CONVERT(DATETIME, CONVERT(CHAR(8), DATEADD(ss,-ConfTask.[LastExecutedDuration], ConfTask.[LastExecutedDate]), 112)) + ' ' + CONVERT(CHAR(8), '05:30:00', 108)

Transacting MS Access query (using IIF() and DATESERIAL()) into T-SQL

I'm trying to convert some MS Access queries to T-SQL to use in SSIS (basically converting Access db to SQL server 2008) and I'm having trouble converting an IIF() statement. I tried several approaches and it always resulted in an error.
The query creates a column with dates that are "original Date + 2 years if the condition is met and original Date + 1 if the condition is not met". The first part of the IIF() eliminates the case of the original year being a leap year and so the possibility of generating a non-existing date.
The original IIF() statement is:
IIf((Day(Date)=29 And Month(Date)=2),
IIf(Desc Like "*" & "123" & "*",
DateSerial(Year(Date)+2,Month(Date),Day(Date)-1),
DateSerial(Year(Date)+1,Month(Date),Day(Date)-1)),
IIf(Desc Like "*" & "123" & "*",
DateSerial(Year(Date)+2,Month(Date),Day(Date)),
DateSerial(Year(Date)+1,Month(Date),Day(Date)))) AS Term
So the problem is not only an IIF() statement but also DATESERIAL function. I found the solution for the DATESERIAL() function using CAST() (SQL server 2008 does not have the DATEFROMPARTS() function...).
I tried using CASE() like this:
CASE
WHEN DAY(Date)=29 AND Month(Date)=2 THEN
CASE
WHEN Desc LIKE "%123%" THEN
CAST(CAST(YEAR(Date)+2 AS VARCHAR(4)) + RIGHT('0' + CAST(MONTH(Date) AS VARCHAR(2)), 2) + RIGHT('0' + CAST(DAY(Date)-1 AS VARCHAR(2)), 2) AS DATETIME )
ELSE CAST(CAST(YEAR(Date)+1 AS VARCHAR(4)) + RIGHT('0' + CAST(MONTH(Date) AS VARCHAR(2)), 2) + RIGHT('0' + CAST(DAY(Date)-1 AS VARCHAR(2)), 2) AS DATETIME ) END
ELSE CASE
WHEN Desc LIKE "%123%" THEN
THEN CAST(CAST(YEAR(Date)+2 AS VARCHAR(4)) + RIGHT('0' + CAST(MONTH(Date) AS VARCHAR(2)), 2) + RIGHT('0' + CAST(DAY(Date) AS VARCHAR(2)), 2) AS DATETIME )
ELSE CAST(CAST(YEAR(Date)+1 AS VARCHAR(4)) + RIGHT('0' + CAST(MONTH(Date) AS VARCHAR(2)), 2) + RIGHT('0' + CAST(DAY(Date) AS VARCHAR(2)), 2) AS DATETIME )END END AS Term
I also tried using COAELSCE() but with no better outcome.
I really don't know if I have made some kind of syntax error or where the problem could be.
Thank you in advance for any help.
edit: I'll add error message I'm getting: Incorrect syntax near '...'. The '...' changes as I try different approaches, sometimes its ELSE, THEN etc.
SQL Server's DATEADD may help to simplify things here...
CASE WHEN (<your condition>)
THEN DATEADD(YEAR, 1, [OriginalDate])
ELSE DATEADD(YEAR, 2, [OriginalDate])
END
Should also cope with leap years too.
DateSerial is such a useful function to have around, just create your own.
I got my version from here:
CREATE FUNCTION dbo.DateSerial
(
#year int,
#month int,
#day int
)
RETURNS datetime
AS
BEGIN
DECLARE #date datetime
-- convert date by adding together like yyyymmdd
SET #date = cast(#year * 10000 + 101 AS char(8));
-- Add to date the proper months subtracting 1, since we used 1 as start instead of zero.
SET #date = dateadd(mm , #month - 1 , #date)
-- Add to date the proper days subtracting 1, since we used 1 as start instead of zero.
SET #date = dateadd(dd , #day - 1 , #date);
RETURN #date ;
END;
GO
Here is another way: Date serial in SQL?
Then use the function just as you did in Access.
Edit: just noticed that your outer IIF is to handle leap years. This is not needed when using dateadd().

Converting date/time in sql to string

Is there any way that I can convert the DateTime SQL value of this:
2011-10-11 00:00:00.000
to a string formatted exactly the same?
'2011-10-11 00:00:00.000'
I tried doing cast(fl_from_dt as varchar(50) but it converts it to something readable - ex. 'Oct 11 2011 12:00AM'
Are you using SqlServer?
Take a look at the style parameter of CONVERT() here: http://msdn.microsoft.com/en-us/library/ms187928.aspx - in particular have a look at the ODBC canonical (with milliseconds) format.
For short you should use style 121 in the CONVERT() command.
Style: 121
ODBC canonical (with milliseconds) default for time, date, datetime2, and datetimeoffset
yyyy-mm-dd hh:mi:ss.mmm(24h)
Try this one !
select CONVERT(VARCHAR(10), GETDATE(), 112)
+ right('0'+cast(datepart(hh, GETDATE()) as varchar(2)),2)
+ right('0'+cast(datepart(mi, GETDATE()) as varchar(2)),2)
+ right('0'+cast(datepart(ss, GETDATE()) as varchar(2)),2) as 'DateTime_STR2'

Unable to convert from Julian INT date to regular TSQL Datetime

Help me Stackoverflow, I'm close to going all "HULK SMASH" on my keyboard over this issue. I have researched carefully but I'm obviously not getting something right.
I am working with a Julian dates referenced from a proprietary tool (Platinum SQL?), though I'm working in SQL 2005. I can convert their "special" version of Julian into datetime when I run a select statement. Unfortunately it will not insert into a datetime column, I get the following error when I try:
The conversion of a char data type to a datetime data type resulted in an out-of-range datetime value.
So I can't setup datetime criteria for running a report off of the Stored Procedure.
Original Value: 733416
Equivalent Calendar Value: 01-09-2009
Below is my code... I'm so close but I can't quite see what's wrong, I need my convert statement to actually convert the Julian value (733416) into a compatible TSQL DATETIME value.
SELECT
org_id,
CASE WHEN date_applied = 0 THEN '00-00-00'
ELSE convert(char(50),dateadd(day,date_applied-729960,convert(datetime, '07-25-99')),101)
END AS date_applied,
CASE WHEN date_posted = 0 THEN '00-00-00'
ELSE convert(char(50),dateadd(day,date_posted-729960,convert(datetime, '07-25-99')),101)
END AS date_posted
from general_vw
SELECT
org_id,
CASE WHEN date_applied = 0 OR date_applied < 639906 THEN convert(datetime, '1753-01-01')
ELSE dateadd(day,date_applied-729960,convert(datetime, '07-25-99'))
END AS date_applied,
CASE WHEN date_posted = 0 OR date_applied < 639906 THEN convert(datetime, '1753-01-01')
ELSE dateadd(day,date_posted-729960,convert(datetime, '07-25-99'))
END AS date_posted
from general_vw
You're casting to char but want a datetime so that's one easy fix.
You were also using '00-00-00' as your minimum date, but the minimum TSQL date is '1753-01-01'. Alternatively you could use something like ('1900-01-01') but that would need a change to the "less than" date_applied comparer.
I've added a "less than" date_applied comparer too. I calculated this as "SELECT 729960 + datediff(day,convert(datetime, '07-25-99'), convert(datetime,'1753-01-01'))". Any number less than this would cause a date underflow.