multiple CASE when statement - snowflake-cloud-data-platform

are these two statement equivalent in snowflake.
Case 1:
CASE
when VAL='ABC' then 'ALPHA'
when VAL='123' then 'NUMERIC'
else 'ALPHANUMERIC'
end;
Case 2:
VOBJECTDESCRIPTION =
CASE WHEN VAL='ABC' THEN 'ALPHA' ELSE
CASE WHEN VAL='123' THEN 'ALPHA' ELSE
'ALPHANUMERIC'
END END;

Well, you've got several typos which make these both different, but given the gist of what you're trying to ask: statements like these both have the same behavior.
WITH X as (
select VAL from (values ('1'), ('2'), ('ABC')) as x(VAL)
)
SELECT CASE
when VAL='ABC' then 'ALPHA'
when VAL='123' then 'NUMERIC'
else 'ALPHANUMERIC'
end
FROM X;
WITH X as (
select VAL from (values ('1'), ('2'), ('ABC')) as x(VAL)
)
SELECT
CASE WHEN VAL='ABC' THEN 'ALPHA'
ELSE
CASE WHEN VAL='123' THEN 'NUMERIC'
ELSE 'ALPHANUMERIC'
END
END
FROM X;
From the parser's perspective, the first option thinks of all the WHENs as siblings, whereas the second one treats the entire second CASE statement as a child of the first ELSE. But I doubt there'd be any measurable difference in performance.
The first syntax is simpler, and I would favor it for readability. Even better, you can do this to avoid duplicative VAL= syntax:
WITH X as (
select VAL from (values ('1'), ('2'), ('ABC')) as x(VAL)
)
SELECT CASE VAL
when 'ABC' then 'ALPHA'
when '123' then 'NUMERIC'
else 'ALPHANUMERIC'
end
FROM X;

Related

How to compare right and left side of a string in SQL

The idea is that if the first name and the last name are the same, the column indicator should put a 'fail' and if not, should enter 'pass'
SELECT TOP 1000
name,
case when CHARINDEX(' ',=name)<>0
and LEFT(TRIM(=name),CHARINDEX(' ',=name)-1)=RIGHT(TRIM(=name),CHARINDEX(' ',c=name)+1) then 'fail'
else 'pass' end AS indicator
FROM Table
I have an entry in the column name that is N/A N/A and I think it should fail with the case I wrote but is giving me a 'pass' I am not sure what could be the problem here
This worked for me, splitting like I usually do it. Although names may not have only one space in them.
with tbl(name) as (
select 'Darth Vader' union all
select 'N/A N/A' union all
select 'joe mama'
)
SELECT name,
case
when SUBSTRING(name,0,CHARINDEX(' ',name)) = SUBSTRING(name,CHARINDEX(' ',name)+1,LEN(name)) then 'fail'
else
'pass'
end AS indicator
FROM tbl;
I think you can just write something simple like this:
CREATE TABLE #TEMP_NAME
(
FIRSTNAME VARCHAR(50),
LASTNAME VARCHAR(50)
)
INSERT INTO #TEMP_NAME
SELECT 'FIRST', 'FIRST'
SELECT 'LAST', 'FIRST'
SELECT
CASE
WHEN PN.FIRSTNAME = PN.LASTNAME THEN 'FAIL'
WHEN PN.FIRSTNAME <> PN.LASTNAME THEN 'PASS'
END AS NAME_PASS_FAIL
FROM #TEMP_NAME PN
query result

How to use a query-results in the same Select statement?

In my select statement I calculate some values and then need to calculate a new value based on the results of the already calculated values. How can this be archived without using a temp table?
SELECT
CASE WHEN [Customer] = '173220000' THEN '1' ELSE NULL END AS Ver_a
, CASE WHEN [Service] = '173220000' THEN '1' ELSE NULL END AS Ver_b
, CASE WHEN [Productavailability] = '173220000' THEN '1' ELSE NULL END AS Ver_c
, (SUM(Ver_a, Ver_b, Ver_c)/3) AS Identity_Ver
FROM x
Just use a sub-query/derived table:
SELECT
Ver_a
, Ver_b
, Ver_c
, (coalesce(Ver_a,0) + coalesce(Ver_b,0) + coalesce(Ver_c,0))/3 AS Identity_Ver
FROM (
SELECT
CASE WHEN [Customer] = '173220000' THEN '1' ELSE NULL END AS Ver_a
, CASE WHEN [Service] = '173220000' THEN '1' ELSE NULL END AS Ver_b
, CASE WHEN [Productavailability] = '173220000' THEN '1' ELSE NULL END AS Ver_c
FROM x
) x
Note 1: as you are not grouping you don't need the sum function, just the sum operator (+) - and the sum function doesn't take a comma separated list of values either.
Note 2: your sum won't work without using the coalesce function as you are returning null from the case expressions.
Firstly, you cannot do sum(var1, var2, var3).
The answer to your question, as stated, seems to be the code at the end.
BUT, I have to ask: what do you want to accomplish? Your approach does make sense to me :-(
SELECT
Sum(
CASE WHEN [customer] = '173220000' THEN 1 ELSE 0 END +
CASE WHEN [service] = '173220000' THEN 1 ELSE 0 END +
CASE WHEN [productavailability] = '173220000' THEN 1 ELSE 0 END
) / 3 AS Identity_Ver
FROM x

SQL - Alias in CASE statements

I have this piece of code (please look below). I keep getting error: "Invalid column name 'SuppFinish2'
SELECT
CASE
WHEN [RegFinish] IS NULL THEN ''
ELSE [RegFinish]
END AS [RegFinish],
CASE
WHEN [SuppFinish] IS NULL THEN ''
ELSE [SuppFinish]
END AS [SuppFinish2],
CASE
WHEN [RegFinish]<[SuppFinish2] THEN '1'
ELSE '0'
END AS [TEST]
FROM TABLE
Is it because of [SuppFinish2] being an alias? Thanks!
As you said its due to alias and aliased columns can be referenced only on order by to logical query flow order
with cte
as
(
SELECT
CASE
WHEN [RegFinish] IS NULL THEN ''
ELSE [RegFinish]
END AS [RegFinish],
CASE
WHEN [SuppFinish] IS NULL THEN ''
ELSE [SuppFinish]
END AS [SuppFinish2]
FROM TABLE
)
select
CASE
WHEN [RegFinish]<[SuppFinish2] THEN '1'
ELSE '0'
END AS [TEST]
from cte
You cant use those aliases in the same level as you created them, becuase they are not existing yet.. wrap your query with another select like this:
SELECT * ,
CASE
WHEN [RegFinish]<[SuppFinish2] THEN '1'
ELSE '0'
END AS [TEST]
FROM (
SELECT
[ID],
CASE
WHEN [RegFinish] IS NULL THEN ''
ELSE [RegFinish]
END AS [RegFinish],
CASE
WHEN [SuppFinish] IS NULL THEN ''
ELSE [SuppFinish]
END AS [SuppFinish2],
FROM TABLE)
In order to reference aliased columns, you can use a derived table (or CTE, but that is not shown here)
Select *, CASE
WHEN [RegFinish]<[SuppFinish2] THEN '1'
ELSE '0'
END AS [TEST] From
(
SELECT
CASE
WHEN [RegFinish] IS NULL THEN ''
ELSE [RegFinish]
END AS [RegFinish],
CASE
WHEN [SuppFinish] IS NULL THEN ''
ELSE [SuppFinish]
END AS [SuppFinish2]
) T1
FROM TABLE
You cannot, at the same time, set and access an alias in the SELECT clause. I would suggest rewriting your query using CROSS APPLY:
SELECT t1.[RegFinish],
t2.[SuppFinish],
CASE
WHEN t1.[RegFinish] < t2.[SuppFinish] THEN '1'
ELSE '0'
END AS [TEST]
FROM TABLE
CROSS APPLY (SELECT COALESCE([RegFinish], '') AS [RegFinish]) AS t1
CROSS APPLY (SELECT COALESCE([SuppFinish], '') AS [SuppFinish]) AS t2
SELECT ISNULL([RegFinish],'') as [RegFinish]
, ISNULL([SuppFinish],'') as [SuppFinish2], CASE
WHEN
ISNULL([RegFinish],'') < ISNULL([SuppFinish],'') THEN 1
ELSE 0
END AS [TEST]
FROM TABLE
Why not use ISNULL instead of CASE? The problem with your query is that [SuppFinish2] is an alias not an column and can only be used in ORDER BY clause

T-SQL Return text in CASE with numeric check

When I do this :
select
'Result' =
case
when my_table.value > 0
then 'Correct'
else 'Not Correct'
end
from table as my_table
It always returns something like this:
Msg 245, Level 16, State 1, Line 1
Conversion failed when converting the varchar value 'Correct' to data type int.
How can I achieve this ? Isn't it possible to return a text value after a numeric check in a CASE statement ?
thanks !
k.
There is nothing technically wrong with your syntax, your query can be fairly easily replicated with:
SELECT 'Result' = CASE WHEN my_table.value > 0 THEN 'Correct'
ELSE 'Not Correct'
END
FROM (VALUES (1), (0)) My_Table (Value);
which works fine. You can do whatever checks you like as long as all the return types are the same, or implicitly convertable to the data type with the highest precedence, e.g. This still works:
SELECT 'Result' = CASE WHEN my_table.value > 0 THEN 1 -- INTEGER/INTEGER
WHEN 'Test' = 'Test2' THEN 0.5 -- TEXT/DECIMAL
ELSE '0' --/TEXT
END
FROM (VALUES (1), (0)) My_Table (Value);
The comment shows the Expresson Type/Return Type. I suspect that the actual problem comes from either a UNION that you have not posted, or further expressions in the case expression that you have not posted.
For example, although the top part runs fine on its own above, running this:
SELECT 'Result' = CASE WHEN my_table.value > 0 THEN 'Correct'
ELSE 'Not Correct'
END
FROM (VALUES (1), (0)) My_Table (Value)
UNION ALL
SELECT 1;
Will give the following error:
Conversion failed when converting the varchar value 'Correct' to data type int.
As an aside, I'd suggest getting away from using literals for column aliases though, for one it is on the deprecation list, but IMO it can also get confusing, especially, as in this case, when combined with actual string literals.
It fails because my_table.Value is of different datatype. try this
;with t
As
(
select
'Result' =
case
when my_table.value > 0
then 1
else 0
end
from table as my_table
)
select CASE WHEN t.Result = 1 then 'CORRECT' ELSE 'WRONG' END FROM t
OR
;with t
As
(
SELECT CASE WHEN my_table.value > 1 THEN 1 ELSE 0 END as Result FROM dbo.my_table
)
select CASE WHEN t.Result = 1 then 'CORRECT' ELSE 'WRONG' END FROM t

How to check for NULL in a CASE statement with a Scalar Function?

How do you check for NULL in a CASE statement, when you're using a Scalar Function?
My original query was ... but it fails
SELECT CASE dbo.fnCarerResponse('')
WHEN NULL THEN 'Pass'
ELSE 'Fail'
END
I read the SO question about using IS NULL, like so ...
SELECT CASE dbo.fnCarerResponse('') IS NULL
WHEN NULL THEN 'Pass'
ELSE 'Fail'
END
but this gives the incorrect syntax near the keyword is error
Can you have a Scalar Function in the CASE ?
You are using the wrong style of CASE - you need to use CASE WHEN <expression> THEN not CASE <expression> WHEN <expression> then:
SELECT CASE
WHEN dbo.fnCarerResponse('') IS NULL
THEN 'Pass'
ELSE 'Fail'
END
SELECT CASE
WHEN dbo.fnCarerResponse('') IS NULL
THEN 'Pass'
ELSE 'Fail'
END
SELECT CASE
WHEN dbo.fnCarerResponse('') is NULL THEN 'Pass'
ELSE 'Fail'
END
You can use this way too:
SELECT CASE ISNULL(dbo.fnCarerResponse(''),'NULLVALUE')
WHEN 'NULLVALUE' THEN 'Pass'
ELSE 'Fail'
END
When used in the context of a list, such as the definitions of the columns of a SELECT query, the entire expression must be wrapped in parentheses, like this.
,LastEditorEmail = (SELECT CASE
WHEN CF.LastModifiedBy IS NULL THEN
NULL
ELSE
UE.Email
END)

Resources