nested case in databricks using spark sql - apache-spark-sql

I am trying to use nested case in spark SQL as in the below query
%sql SELECT CASE WHEN 1 > 0 THEN
CAST(CASE WHEN 2 > 0 THEN 2.0 ELSE 1.2 END AS INT)
ELSE "NOT FOUND "
however, I am coming across the error
Error in SQL statement: ParseException:
mismatched input '1' expecting {<EOF>, ';'}(line 1, pos 17)
== SQL ==
SELECT CASE WHEN 1 > 0 THEN
-----------------^^^
CAST(CASE WHEN 2 > 0 THEN 2.0 ELSE 1.2 END AS INT)
ELSE "NOT FOUND "
does databricks support nested case statement? and if yes, then please suggest what is the issue in the above code.

spark.sql("""
SELECT CASE WHEN 1 > 0 THEN CAST(CASE WHEN 2 > 0 THEN 2.0 ELSE 1.2 END AS INT)
ELSE 'NOT FOUND' END AS select_case
""").show(10)
+-----------+
|select_case|
+-----------+
| 2|
+-----------+

Related

Bigquery if null and 0 then condition

I would like to add a condition if the row value is null or 0 then 0 else 1.
SELECT CASE WHEN NUM_FRIEND IS NULL AND 0 THEN 0 ELSE 1 END AS friends_column
FROM TABLE
I get the following error:
No matching signature for operator and
As a case expression, the syntax is:
SELECT (CASE WHEN NUM_FRIEND IS NULL OR NUM_FRIEND = 0 THEN 0 ELSE 1 END) AS friends_column
FROM TABLE;
You can simplify this to:
SELECT (CASE WHEN NUM_FRIEND <> 0 THEN 1 ELSE 0 END) AS friends_column
FROM TABLE;
Or, instead of 0 and 1, return a boolean:
SELECT (NUM_FRIEND <> 0) AS friends_column
FROM TABLE;

select query to identify numeric or alphanumeric values

I have a table like below:
TN Tier
90 1
90 N3
30 2
40 3
50 A
"Tier" column may contain numeric as well as alpha-numeric values for any TN. I want to run a select query on above table so that if for any TN, there are both(numeric and alpha-numeric) values present in Tier column then it should be called as "Mix" otherwise "Numeric" or "Non-Numeric".
Desired Output :
TN Result
90 Mix
30 Numeric
40 Numeric
50 Non-Numeric
I am able to achieve it by using multiple temp tables but i want to avoid using temp tables. Any help would be appreciated!!!
You can take use advantage of ISNUMERIC() function in SQL Server.
SELECT [TN],
CASE MAX(ISNUMERIC(Tier)) + MIN(ISNUMERIC(Tier))
WHEN 2 THEN 'Numeric'
WHEN 1 THEN 'Mix'
ELSE 'Non-Numeric'
End As Result
FROM TableName
GROUP BY TN
Here's a Demo.
For MySQL, use REGEXP with a CASE expression:
SELECT
TN,
CASE WHEN SUM(CASE WHEN Tier REGEXP '[A-Z]' AND Tier REGEXP '[0-9]'
THEN 1 ELSE 0 END) > 0 THEN 'Mix'
WHEN SUM(CASE WHEN Tier REGEXP '[A-Z]'
THEN 1 ELSE 0 END) > 0 THEN 'Non-Numeric'
WHEN SUM(CASE WHEN Tier REGEXP '[0-9]'
THEN 1 ELSE 0 END) > 0 THEN 'Numeric'
ELSE 'Other' END AS Result
FROM yourTable
GROUP BY
TN;
For SQL Server, you may slightly alter the above query by using LIKE with an appropriate pattern:
SELECT
TN,
CASE WHEN SUM(CASE WHEN Tier LIKE '%[A-Z]%' AND Tier LIKE '%[0-9]%'
THEN 1 ELSE 0 END) > 0 THEN 'Mix'
WHEN SUM(CASE WHEN Tier LIKE '%[A-Z]%'
THEN 1 ELSE 0 END) > 0 THEN 'Non-Numeric'
WHEN SUM(CASE WHEN Tier LIKE '%[0-9]%'
THEN 1 ELSE 0 END) > 0 THEN 'Numeric'
ELSE 'Other' END AS Result
FROM yourTable
GROUP BY
TN;
The SQL Server answer given by #JohnWoo is tighter than this, but as you tagged with MySQL I initially answered for this database.
You dont need any big query it can be make with simple,
try this:
Select * from table
then you can check value of you column in while loop, each time you can search string having number or not number in you record.
$string = $row['Tier'];
if (preg_match('/[A-Za-z]/', $myString) )
{
echo 'String contains letters';
}
else if(preg_match('/[0-9]/', $myString))
{
echo 'String contains numbers';
}else if($string == '')
{
echo 'String contains no letter and no number';
}
I hope, you are using mysql. It is better if you can write a custom function as follows.
delimiter //
CREATE FUNCTION is_numeric(inputValue VARCHAR(50))
RETURNS INT
BEGIN
IF (inputValue REGEXP ('^[0-9]+$'))
THEN
RETURN 1;
ELSE
RETURN 0;
END IF;
END;
Example - select is_numeric(id),is_numeric(full_name) FROM tbl_user;

check if value is numeric in sql view

What is wrong with my case statement below?
If the value is numeric then I want to check if its greater than or equal to 5 and return 1 if true else return 0. Is there any elegant way of doing this?
Below CASE is nested in another CASE
CASE
WHEN(
xyz <> a
AND abc <> 3
AND
CASE
WHEN ISNUMERIC(LEFT(o.RepCode, 1)) = 1 THEN
CASE
WHEN CONVERT(INT, LEFT(o.RepCode, 1)) >= 5 THEN 1
ELSE 0
END
ELSE 0
END
)
THEN 1
ELSE 0
I get the below error on the first CASE after the second AND before WHEN ISNUMERIC()
An expression of non-boolean type specified in a context where a condition is expected.
Missing criteria in your outermost case statement:
CASE
WHEN(
xyz <> a
AND abc <> 3
AND
CASE
WHEN ISNUMERIC(LEFT(o.RepCode, 1)) = 1 THEN
CASE
WHEN CONVERT(INT, LEFT(o.RepCode, 1)) >= 5 THEN 1
ELSE 0
END
ELSE 0
END = ? -- Missing criteria
)
THEN 1
ELSE 0
Edit: Not sure there's an ideal way to format this, but I find the following to be easier to follow:
CASE WHEN ( xyz <> a
AND abc <> 3
AND CASE WHEN ISNUMERIC(LEFT(o.RepCode, 1)) = 1
THEN CASE WHEN CONVERT(INT, LEFT(o.RepCode, 1)) >= 5
THEN 1
ELSE 0
END
ELSE 0
END = ? -- Missing Criteria
)
THEN 1
ELSE 0
END

AND and OR operator in SQL Server

Is the AND operator in SQL Server equivalent to && or & in C# (or other languages)?
Ie, will it check for second condition if first condition is found to be false?
No, there is no short-circuiting in SQL. For example:
SELECT a, b, c
From T t
WHERE is_numeric(c) = 1 AND cast(c as numeric(10,2)) > 100.00
This may generate an invalid cast error where c is not numeric.
However you can force it to short-circuit by re-writing to use a CASE statement:
SELECT a, b, c
From T t
where
case
when is_numeric(c) = 0 then 0
when cast(c as numeric(10,2)) > 100.00 then 1
else 0
end = 1
In general and with the exception of handling nulls any clause of the form
where <EXPR1> AND <EXPR2> AND <EXP3>
can be written as:
where case
when NOT <EXPR1> then 0
when NOT <EXPR2> then 0
when NOT <EXPR3> then 0
else 1 end = 1
Any expression of the form:
where <EXPR1> OR <EXPR2> OR <EXPR3>
Can be written as:
where case
when <EXPR1> then 1
when <EXPR2> then 1
when <EXPR3> then 1
else 0 end = 1

SQL Query - Can I compare using LEN in SELECT clause?

I basically want to do this:
SELECT HasComments = CASE (LEN(Comments) > 1) WHEN 1 THEN 1 ELSE 0 END FROM TableName
In other words, return a boolean telling me whether the length of Comments is greater than 1. This gives me a syntax error.
How can I accomplish this?
SELECT HasComments = CASE WHEN LEN(Comments) > 1 THEN 1 ELSE 0 END
FROM TableName
A better way would be to make Comments NULLable and check for that. Indexes could then be leveraged instead of the table-scan LEN() will cause.
you're missing the when and end
SELECT HasComments = CASE WHEN (LEN(Comments) > 1) WHEN 1 THEN 1 ELSE 0 END
FROM TableName
Since you have no WHERE clause, you're most likely returning a column of data:
SELECT CASE WHEN LEN(Comments) > 1 THEN 1 ELSE 0 END as 'HasComments'
FROM TableName
For newer SQL versions:
SELECT CASE WHEN LEN(Comments) > 1 THEN 1 ELSE 0 END FROM TableName