If not <> NULL then "xxxField" equals '1' - sql

I have a feeling this is a fairly simple one. I need to edit a line in the SELECT statement that looks to see if there is a value of NULL in a field. If there is a NULL value, I need the new column (not named) to display a '0' for that row. Where the row has data I need to display '1' in that row. Is there a way to do this without greatly modifying the logic I have? (Using SQL Server Management Studio)
Here's the code:
SELECT DISTINCT t.Name,
CONVERT(VARCHAR(10), t.DischargeDateTime, 120) AS DischargeDate,
t.PatientPortalEnabled,
t.Allergy,
CONVERT(VARCHAR(10), t.AllergyUpdateTime, 120) AS AllergyUpdate,
/*This is where I would like to put the logic if possible*/ <> NULL,
t.ElapseTimeForAllergyUpdateInMinutes,
t.OldValue,
t.NewValue,
t.ElapseTimeForAllergyUpdateInHours,
t.DischargeDateTime

Try this:
CASE WHEN MyField IS NULL THEN 0 ELSE 1 END
Here it is in your code:
SELECT DISTINCT t.Name,
CONVERT(VARCHAR(10), t.DischargeDateTime, 120) AS DischargeDate,
t.PatientPortalEnabled,
t.Allergy,
CONVERT(VARCHAR(10), t.AllergyUpdateTime, 120) AS AllergyUpdate,
CASE WHEN t.MyField IS NULL THEN 0 ELSE 1 END,
t.ElapseTimeForAllergyUpdateInMinutes,
t.OldValue,
t.NewValue,
t.ElapseTimeForAllergyUpdateInHours,
t.DischargeDateTime

You can do this using a CASE statement.
SELECT DISTINCT t.Name,
CONVERT(VARCHAR(10), t.DischargeDateTime, 120) AS DischargeDate,
t.PatientPortalEnabled,
t.Allergy,
CONVERT(VARCHAR(10), t.AllergyUpdateTime, 120) AS AllergyUpdate,
/*This is where I would like to put the logic if possible*/
CASE
WHEN t.MyField IS NULL THEN 0
ELSE 1
END AS MyNewField,
t.ElapseTimeForAllergyUpdateInMinutes,
t.OldValue,
t.NewValue,
t.ElapseTimeForAllergyUpdateInHours,
t.DischargeDateTime

Using XOR bitwise operator:
declare #x int = null
select isnull((#x ^ #x),-1)+1

Related

How to change parameter value in query dialog Jaspersoft?

To run my report I need to set parameter $P{P_CLIENT_TYPE} to one of three strings: "Insured" , "Policy Holder" or "BOTH". I would like to use shorter versions: "INS", "PH" and "%".
How to convert later these 3 short parameters in my query dialog, so instead of "PH" it will know that it means "Insured"?
My query looks like below:
select distinct (SELECT MIN(INS_FROM)
FROM [dbo].[INSURANCE_DB]
where [CLIENT_TYPE] like $P{P_CLIENT_TYPE}
and code_type =$P{P_CODE_TYPE}
and code = $P{P_COD}
) MIN_INS_FROM
,IIF( x.max1 > DATEADD(day, -1, GETDATE())
,DATEADD(day, -1, GETDATE())
, x.max1
) MAX_INS_TO
I tried to make replace function or convert function at the beginning of the query but nothing seems to work.
I have found the solution, it was quite simple. I just needed to use CASE WHEN ... THEN
select distinct (SELECT MIN(INS_FROM)
FROM [dbo].[INSURANCE_DB]
where [CLIENT_TYPE] like
**CASE
WHEN $P{P_CLIENT_TYPE} = 'INS' THEN 'Insured'
WHEN $P{P_CLIENT_TYPE} = 'PH' THEN 'Policy Holder'
ELSE '%'
END**
and code_type =$P{P_CODE_TYPE}
and code = $P{P_COD}
) MIN_INS_FROM
,IIF( x.max1 > DATEADD(day, -1, GETDATE())
,DATEADD(day, -1, GETDATE())
, x.max1
) MAX_INS_TO

CONCAT leading 0 in case statement

I found an error in a query I inherited from a previous coworker that I am trying to fix but it's a weird issue I haven't encountered before.. here is a snip of the original query:
CAST(CONCAT(DATEPART(YYYY,getdate()),
(CASE
WHEN DATEPART(WW,getdate()) < 10
THEN CONCAT('0', DATEPART(WW,getdate()))
ELSE DATEPART(WW,getdate())
END)
) AS INT)
When getdate() = 2021-01-08 10:16:41.440 the query results in
20212
Expected result should be
202102
I found the issue relies in in the CASE statement. When I tried to change the THEN clause to
CAST(CONCAT(DATEPART(YYYY,getdate()),
(CASE
WHEN DATEPART(WW,getdate()) < 10
THEN RIGHT('0'+ CONVERT(VARCHAR(2), DATEPART(WW,getdate())),2)
ELSE DATEPART(WW,getdate())
END)
) AS INT)
I still get
20212
But when I run
SELECT RIGHT('0'+ CONVERT(VARCHAR(2), DATEPART(WW,getdate())),2)
I get
02
Can someone explain this? Why does it work outside of the CASE statement, but not within?
case expressions return a single value and that has a single type. If any of the return values are numbers, then the return value is a number, not a string.
To get a string, use datename():
(CASE WHEN DATEPART(WW, getdate()) < 10
THEN CONCAT('0', DATENAME(WW,getdate()))
ELSE DATENAME(WW, getdate())
END)
Or you could simplify your logic:
RIGHT(CONCAT('0', DATENAME(WW, getdate()), 2)
Or simplify everything. For instance, a number might be sufficient:
YEAR(GETDATE()) * 100 + DATEPART(WW, getdate())
Your query has implicit cast to INT:
CAST(CONCAT(DATEPART(YYYY,getdate()),
(CASE
WHEN DATEPART(WW,getdate()) < 10
THEN RIGHT('0'+ CONVERT(VARCHAR(2), DATEPART(WW,getdate())),2)
ELSE CAST(DATEPART(WW,getdate()) AS VARCHAR(2)) -- adding explicit cast here
END)
) AS INT)
I can advice the simple way:
SELECT
CAST(
CONCAT(
DATEPART(YYYY,getdate()),
RIGHT(CONCAT('0000', DATEPART(WW,getdate())), 2)
) AS INT);
You can try T-SQL here

How to skip values that have NULL values in a TSQL query?

I have this rather complex query:
SELECT distinct
v.KodQ, v.DodPeriodika,
v.GodGP, v.Periodika as Period,
k.Oblast, k.KratokNazivSI,
k.NazivSI, k.Periodika,
v.rKod, r.Naziv,
v.rDatum,
v.IT, v.Primerok, v.BrojIE,
CONVERT(varchar, CONVERT(DATETIME, v.RefPeriodOd), 103) as RefPeriodOd,
CONVERT(varchar, CONVERT(DATETIME, v.RefPeriodDo), 103) as RefPeriodDo
FROM GP.dbo.MyTable1 AS v
INNER JOIN GP.dbo.MyTable2 as k
ON k.KodSI = v.KodQ AND k.DodObr = v.DodPeriodika
INNER JOIN GP.dbo.MyTable3 AS r
ON r.rKod = v.rKod
WHERE v.GodGP = GodGP and CHARINDEX('-', RefPeriodDo, 0) != 0
I need to convert v.RefPeriodOd and v.RefPeriodDo from this format '31-Dec-2017' to this format '31/12/2017'.
Yes I know saving DateTime as string(varchar) is bad idea, but the application is now in use so I cannot really do QA at the moment and refactor my table.
I am using this statement:
CONVERT(varchar, CONVERT(DATETIME, v.RefPeriodDo), 103) as RefPeriodDo
But the problem is, v.RefPeriodOd and v.RefPeriodDo can have a NULL values and also values in the format: '31/12/2017'
If I remove this condition:
CHARINDEX('-', RefPeriodDo, 0) != 0
I get this error:
The conversion of a nvarchar data type to a datetime data type
resulted in an out-of-range value.
How can I add some conditions in the query?
Does IF statement exists in TSQL?
Change
CONVERT(varchar, CONVERT(DATETIME, v.RefPeriodOd), 103) as RefPeriodOd
for
CASE
WHEN CHARINDEX('-', RefPeriodDo, 0) != 0
THEN CONVERT(varchar, CONVERT(DATETIME, v.RefPeriodOd), 103)
END as RefPeriodOd
And remove the filter in the WHERE.
"IFs" are expressed with the CASE clause if inside SELECT statements, and the most common syntax is the following:
CASE
WHEN 1stCondition THEN 1stValue
WHEN 2ndCondition THEN 2ndValue
ELSE DefaultValue -- Else is optional
END
Conditions are evaluated in order, and if no ELSE is issued, then NULL is returned.
Try to add to the where the following:
WHERE (v.RefPeriodOd is not null and v.RefPeriodOd <> '')
AND (v.RefPeriodDo is not null and v.RefPeriodDo <> '')
Note:
You cannot put the condition in the WHERE clause. The filtering is not necessarily before the expressions in the SELECT.
You should always include a length for strings in SQL Server.
The right way to handle this is try_convert():
TRY_CONVERT(varchar(255), TRY_CONVERT(DATETIME, v.RefPeriodOd), 103) as RefPeriodOd,
TRY_CONVERT(varchar(255), TRY_CONVERT(DATETIME, v.RefPeriodDo), 103) as RefPeriodDo
TRY_CONVERT() is available since SQL Server 2012. Before that, you needed to use a CASE to avoid conversion errors.
In my opinion, the filter condition should be:
RefPeriodDo LIKE '%-%'
I think this is easier to write and to read.
Try this:
SELECT distinct
v.KodQ, v.DodPeriodika,
v.GodGP, v.Periodika as Period,
k.Oblast, k.KratokNazivSI,
k.NazivSI, k.Periodika,
v.rKod, r.Naziv,
v.rDatum,
v.IT, v.Primerok, v.BrojIE,
CONVERT(varchar, CONVERT(DATETIME, v.RefPeriodOd), 103) as RefPeriodOd,
CONVERT(varchar, CONVERT(DATETIME, v.RefPeriodDo), 103) as RefPeriodDo
FROM GP.dbo.MyTable1 AS v
INNER JOIN GP.dbo.MyTable2 as k
ON k.KodSI = v.KodQ AND k.DodObr = v.DodPeriodika
INNER JOIN GP.dbo.MyTable3 AS r
ON r.rKod = v.rKod
WHERE v.GodGP = GodGP AND ISNULL(v.RefPeriodOd,'')<>'' AND ISNULL(v.RefPeriodDo,'')<>''
Filter the rows using WHERE:
WHERE v.GodGP = GodGP AND ISNULL(v.RefPeriodOd,'')<>'' AND ISNULL(v.RefPeriodDo,'')<>''
Give this as try
Note the double use of 103
declare #D table (id int identity primary key, dt varchar(20));
insert into #D (dt) values (null), ('messy'), ('31-Dec-2017'), ('31/12/2017'), ('1/12/2017');
select d.dt
, TRY_CONVERT(DATETIME, d.dt, 103) as dt103
, isnull(TRY_CONVERT(varchar(20), TRY_CONVERT(DATETIME, d.dt, 103), 103), d.dt) dt103var
from #D d;
dt dt103 dt103var
-------------------- ----------------------- --------------------
NULL NULL NULL
messy NULL messy
31-Dec-2017 2017-12-31 00:00:00.000 31/12/2017
31/12/2017 2017-12-31 00:00:00.000 31/12/2017
1/12/2017 2017-12-01 00:00:00.000 01/12/2017

SQL: Cast Not working in SubString

We have a string field for date of birth and now we have to convert it in order to perform the calculations required. However when we are using CAST or CONVERT to convert to perform the calculations it is not working.
select distinct(ptr.RecordID)
from dbo.PatientRecord as ptr
where
ptr.CHName like 'Access2Loc%'
AND ptr.RecordID
in(
select
(
case when
(DATEDIFF(hour, convert(date,DOB,110), GETDATE())/8766)>18
then PatientID
else NULL
end
) as RecordID
from
PatientView
where ISDATE(DOB) = 1
)
SQL Server considers this a "feature". It is hard to explain, but the where is not necessarily executed before the select.
In SQL Server 2012+, use try_convert() (or try_cast():
where ptr.CHName like 'Access2Loc%' and
ptr.RecordID in (select (case when DATEDIFF(hour, try_convert(date, DOB, 110), GETDATE()) / 8766 > 18
then PatientID
end) as RecordID
from PatientView
where ISDATE(DOB) = 1
)
In more ancient versions, you can use a case expression for much the same effect.
-- this will guarantee that ##t1 contains only valid dob rows
if object_id('tempdb..##t1') is not null
drop table #t1
select * into ##t1 from patientview where isdate(dob)=1
select distinct(ptr.RecordID)
from dbo.PatientRecord as ptr
where
ptr.CHName like 'Access2Loc%'
AND ptr.RecordID
in(
select
(
case when
(DATEDIFF(hour, convert(date,DOB,110), GETDATE())/8766)>18
then PatientID
else NULL
end
) as RecordID
from
##t1
)
drop table ##t1

SQL replace using SELECT and invalid column

I have a simple table where the date column answer_6 (formatted as varchar(max) either has a valid date or string Now. I wanted to substitute the Now with the current date/time and then calculate the difference. Here is what I did:
select
CASE [answer_6]
WHEN 'Now' THEN CONVERT(varchar, GETDATE())
ELSE answer_6
END as x,
answer_6 from [tDataMult] where DATEDIFF(yy, GETDATE(), [x]) > 5
The system give me invalid column name 'x'. If I remove the DateDiff SELECT statement works fine.
You can't use aliases in the WHERE clause of the same level as it was defined as WHERE clause is evaluated before the SELECT clause. Try the following :
SELECT t.* FROM (<...>) t WHERE DATEDIFF(yy, GETDATE(), [t.x]) > 5
Instead <...> put your query without WHERE clause.
You can't refer to an alias you've just created in a WHERE clause. The easiest way to fix it would just be to turn your original query into a subquery:
SELECT *
FROM
(
select
CASE [answer_6]
WHEN 'Now' THEN CONVERT(varchar, GETDATE())
ELSE answer_6
END as x,
answer_6 from [tDataMult]
) AS qry
WHERE DATEDIFF(yy, GETDATE(), [x]) > 5
Or you could replicate the expression in your WHERE clause:
select
CASE [answer_6]
WHEN 'Now' THEN CONVERT(varchar, GETDATE())
ELSE answer_6
END as x,
answer_6 from [tDataMult]
WHERE DATEDIFF(yy, GETDATE(),
(CASE [answer_6]
WHEN 'Now' THEN CONVERT(varchar, GETDATE())
ELSE answer_6
END)
) > 5
Column X does not exist in tDataMult table because it is an alias.
Replace it with answer_6 in DateDiff function.
However, one of the possible value of answer_6 column is varchar format ('Now').
You need to have valid data format to use DATEDIFF function properly. (for example: 'yyyy-mm-dd').