Boolean expression in SQL - sql-server

I have two ints: #RecurremceTemp and #WeekDifference
The following line errors:
PRINT #WeekDifference >= #RecurrenceTemp
with Incorrect syntax near '>'
And won't execute.
Can someone please tell me how to write such a boolean expression to include in a Select statement i.e.:
Select *
FROM TableX
WHERE somevariable = x
and #WeekDifference >= #RecurrenceTemp

Predicates cannot be used in expressions, only in IF and WHILE and CASE WHEN:
PRINT CASE WHEN #WeekDifference >= #RecurrenceTemp THEN 1 ELSE 0 END

Your query ought to work just fine.
The reason that the print statement fails is due to the fact that SQL Server treats the results of a boolean expressions very differently than other data types. See Operators:
Unlike other SQL Server data types, a
Boolean data type cannot be specified
as the data type of a table column or
variable, and cannot be returned in a
result set.

Return -1, 0, or 1 from a CASE statement, depending on the comparison. In SQL Sevrer, there is no boolean data type. The nearest data type is BIT, which can have a value of 1, 0 or null.
EDIT:
Your SQL statement
Select *
FROM TableX
WHERE somevariable = x
and #WeekDifference >= #RecurrenceTemp
will select all fields from TableX where somevariable = x and the WeekDifference variable value is greater than or equal to the RecurrenceTemp variable value. Is that not what you want?

Related

Leetcode SQL 1440. Evaluate Boolean Expression

Table Variables:
Column Name
Type
name
varchar
value
int
name is the primary key for this table.
This table contains the stored variables and their values.
Table Expressions:
Column Name
Type
left_operand
varchar
operator
enum
right_operand
varchar
(left_operand, operator, right_operand) is the primary key for this table.
This table contains a boolean expression that should be evaluated.
operator is an enum that takes one of the values ('<', '>', '=')
The values of left_operand and right_operand are guaranteed to be in the Variables table.
Write an SQL query to evaluate the boolean expressions in Expressions table.
Return the result table in any order.
I am working on a SQL problem as shown in the above. I used MS SQL server and tried
SELECT
left_operand, operator, right_operand,
IIF(
(left_values > right_values AND operator = '>') OR
(left_values < right_values AND operator = '<' ) OR
(left_values = right_values AND operator = '='), 'true', 'false') as 'value'
FROM
(SELECT *,
IIF(left_operand = 'x', (SELECT value FROM Variables WHERE name='x')
, (SELECT value FROM Variables WHERE name='y')) as left_values,
IIF(right_operand = 'x', (SELECT value FROM Variables WHERE name='x')
, (SELECT value FROM Variables WHERE name='y')) as right_values
FROM Expressions) temp;
It works well on the test set but gets wrong when I submit it.
I think my logic is correct, could anyone help take a look at it and let me know what my problem is?
Thank you!
It feels like your example code is a lot more complicated than it needs to be. That's probably why it's failing the check. In your FROM you're using sub-selects but really a simple inner join would work much simpler. Also, if there were variables other than X and Y it doesn't look like your example code would work. Here's my code that I wrote in Postgres (should work in any SQL though).
SELECT e.left_operand, l.value as left_val, e.operator, e.right_operand, r.value as right_val,
CASE e.operator
WHEN '<' THEN
(l.value < r.value)
WHEN '=' THEN
(l.value = r.value)
WHEN '>' THEN
(l.value = r.value)
END as eval
FROM
expression as e
JOIN
variable as l on e.left_operand = l.name
JOIN
variable as r on e.right_operand = r.name
Here's a screenshot of my output:
I also have a db-fiddle link for you to check out.
https://www.db-fiddle.com/f/fdnJVSUQHS9Vep4uDSe5ZP/0

SQL Server add condition dynamically using case

In my SQL Server stored procedure, I want to add a Where clause as dynamic as follows:
AND CASE WHEN #mySt <> '' THEN s.myStatus IN(#mySt) ELSE 0=0 END
When I want to check is: if #mySt is not empty, I want to add s.myStatus IN(#mySt).
If if #mySt is empty, I want to skip this where clause.
I get an error
Incorrect syntax near 'IN'
CASE is an expression, it returns a scalar value not a boolean result; you can't do want you're trying to do as s.myStatus IN(#mySt) isn't a scalar value.
Use proper boolean logic:
AND (s.myStatus = #mySt OR #mySt IS NULL) --I suggest NULL over a blank string
I replaced IN with =, as #mySt is a scalar value, so IN and = would be synonyms.

Sql: Casting INT to string

TableA
OFIPS int null,
DFIPS int null
Query below returns a record.
SELECT OFIPS from TableA Where OFIPS = 01077
But this query doesn't.
SELECT OFIPS from TableA Where CAST(OFIPS as nvarchar(5)) = '01077'
Not sure what the problem is. Please help.
Because in int column leading zero's will be ignored, 01077 will be stored as 1077 and when you query like
Where OFIPS = 01077
It will be parsed as
Where OFIPS = 1077
There will be a record stored as 1077 so you are getting result.
But when you query like
Where CAST(OFIPS as nvarchar(5)) = '01077'
It checks for the records with 01077 thats why you are not getting result in second query
Interestingly if you remove the CAST in Where clause again it will work. Even though you query with leading zero in string format.
Where OFIPS = '01077'
Because LHS OFIPS has INT datatype which has higher precedense than the RHS Varchar. Implicitly string in the RHS(01077) will be converted to int 1077
Implicit Conversion
When an operator combines two expressions of different data types, the rules for data type precedence specify that the data type with the lower precedence is converted to the data type with the higher precedence.
https://learn.microsoft.com/en-us/sql/t-sql/data-types/data-type-precedence-transact-sql
Meaning, that '01234' = 1234 will result to TRUE, since '01234' will be converted to INT. INT has a higher precdence.
Explicit conversion
Converting INT to VARCHAR - like CONVERT(VARCHAR(5), 1234) - will not add leading zeros therefore '01234' not equals to CONVERT(VARCHAR(5), 1234).
You can forcibly add the leading zeros if you have a fixed length: RIGHT(CONCAT('00000', CONVERT(CHAR(5), 1234)), 5)
Remarks
Consider to keep the INT-INT comparison, force convert the input values to INT instead of converting the column values.
If the above is not possible, consider to store the values in the database as fixed length character values (CHAR(5)) and make sure, that the INSERT and UPDATE statements are transforming the values to their desired format.
Your column is int and the only int that can have a leading 0 is 0.
Other numbers have no leading 0 because they are not strings but numbers.
When you search for Where OFIPS = 01077 01077 is implicitly converted to 1077,
and this number exists in your table.
When you do CAST(OFIPS as nvarchar(5)) no leading 0 can appear so no one number will be casted to '01077'
You can use this because OFIPS of type is int. Int type is not '01077'. I hope that it help you.
SELECT OFIPS from TableA Where CAST(OFIPS as nvarchar(5)) = '1077'

Inconsistent result from isnumeric

I have the following queries.
select ISNUMERIC(result+ 'E0'), from t1
select ISNUMERIC('7' + 'E0')
select ISNUMERIC('7' + '.E0')
The data type of result column is varchar(50).The first query yields 0 even when result is like 2,3 and returns 1 for float only ...Whereas second and third query works fine for both integer and float.Am I missing anything? My requirement is to check whether result column is number(integer,float) or not.I know isnumeric returns 1 for type like money,small money,real etc but this is not the case here as i don't have such type in my result and i am only receiving 0.
The reason for the seemingly inconsistent result might be, that there is a space in your result column value. Try timming text and feed the trimmed text to ISNUMERIC:
select ISNUMERIC(ltrim(rtrim(result))+ 'E0') from t1

Why I got an int datatype when using conditional case?

Consider the following Sql snippet:
declare #param as int
set #param=1
select
case when #param=1 then '987' else '' end as Value1,
case when #param=2 then 987 else '' end as Value2,
case when #param<>2 then '' else 987 end as Value3
I would expect to get 1 row with 3 fields: The string 987 and 2 empty strings but I get the following result:
Can you explain me please why I got a 0 value? I know it is because the column is interpreted as integer datatype but not sure the reason why.
At the moment of writing the question I found the answer:
This behaviour is due to the Data Type Precedence
When an operator combines two expressions of different data types, the rules for data type precedence specify that the data type with the lower precedence is converted to the data type with the higher precedence. If the conversion is not a supported implicit conversion, an error is returned. When both operand expressions have the same data type, the result of the operation has that data type.
for more information
https://msdn.microsoft.com/en-us/library/ms190309.aspx

Resources