In most RDBMS:es, this work:
select (5 > 3)
and evaluates to true. It doesn't work in MS Transact SQL and the only workaround I've found is to write:
select case when 5 > 3 then 1 else 0 end
Which kind of sucks because it is much more verbose. Is there a better way to write the above kind of checks?
If the problem is arithmetic comparison:
select (5 - 3)
Then at the application level test for < or = or > 0.
You could write it as a scalar-valued function, but it will be very slow on large datasets.
If your program often requires such case constructs you could create your set of functions that will have user functions like Bool_IsGreater(left, right) that will return you your desired 0 or 1.
SQL Server doesn't support boolean value type anyway even for basic column use.
If you will need performance and those 5 and 3 values come naturally from some select query you might want to create a new column and set its value to 1 or 0 by trigger or something, which could help with performance.
Related
I have a QRY im developing in Oracle for spotfire. In the where statement, I have a decision case statement and if its True, im trying to pass a list of items to match a column, below is what I have, but its throwing a missing right parenthesis error and I cannot determine why. In short, when a variable is determined True (in this case 9>8 for the example, I need it to result those items, else, result the entire column with no limits.
Note: This works fine when its only 1 item being passed, i.e. 'BOB' but as soon as its multiple, this error occurs.
and Column1 = (CASE When 9>8 Then ('BOB','TOM') Else Column1 END)
Case expressions are best avoided in the where clause. Instead, write the logic with AND and OR:
And (
(9>8 AND Column1 IN ('BOB','TOM'))
OR 9<=8 -- You say you check a variable here, don't forget to check for NULL
)
Oracle does not have a boolean type for use in SQL queries.
Instead, just use basic logic:
and ( (9 > 8 and Column1 in ('BOB','TOM')) or
9 <= 8
)
If I let MySQL execute SELECT (0 < 1), it return 1; But if I run this select statement with SQL Server, it give me an error:
Incorrect syntax near '<'.
I also have tested other operator like != and <, and get the same error. I'm confused. '0 < 1' is an expression, why can't SQL Server evaluate it?
This behavior is by design:
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.
[...]
Expressions with Boolean data types are used in the WHERE clause to
filter the rows that qualify for the search conditions and in
control-of-flow language statements such as IF and WHILE
So Boolean datatype exists, you just cannot use it outside WHERE clause (etc).
The correct SQL Server equivalent of MySQL SELECT x < 1 (which returns 0, 1 or NULL) would be:
SELECT CASE
WHEN x < 1 THEN 1
WHEN NOT (x < 1) THEN 0
ELSE NULL -- you can omit this line
END
Finally, LEN(NULL) is NULL and (generally speaking) any operation on NULL yields NULL. So the condition IF LEN(NULL) < 1 will not execute, neither will IF LEN(NULL) >= 1.
MS SQL doesn't have a boolean type. It supports boolean expressions, but those cannot be values in variables or result sets.
The best you can do is something like
select case when 0 < 1 then 0 else 1 end
The result set will have a normal integer (the bit type is sometimes used to represent true/false values, but it's just a number with possible values of 1 and 0).
I'm confused. '0 < 1' is an expression, why can't SQL Server evaluate it?
It sort of is and sort of isn't. It's a predicate, and SQL Server treats predicates differently from other expressions which produce values.
SQL Server doesn't have a user-visible boolean data type so you cannot write an expression that produces a value of this non-existent data type.
You can only use predicates in specific positions, such as the WHERE clause, ON clauses, WHEN clauses (part of a CASE expression) and CHECK constraints (there are others)
SQL Server does not seem to support selecting Boolean result.
Example:
Select True;
Or
Select 1>2;
would return an Error.
However, in the majority of programming languages a similar operation is valid. Is there a reason for that?
SQL is not designed for deductive statements. however you can achieve similar results using a statement like this:
SELECT CASE WHEN 2 > 1 THEN 1 ELSE 0 END
how can I convert to T-Sql this one?
IIf([ESSValue]<>0,Int([ESSValue]*100),"")
I think the following pretty much does what you want:
select coalesce(cast(EssValue * 100 as int), 0)
Here is the thinking. The comparison to zero is unimportant, because 0 times any value is going to be zero. The iif() returns an integer (I think) because the "then" argument is an integer; the empty string gets converted to zero.
I'm not 100% certain about the last statements with regard to MS Access, but that is how iif() works in SQL Server.
I should add. Although I don't approve of iif() for conditional expressions (because case is the standard and more powerful), SQL Server does support it. So you could write:
IIf([ESSValue]<>0, cast([ESSValue]*100 as int), '')
Note: As I mentioned earlier, the '' will be converted to 0.
CASE WHEN ESSValue <> 0
THEN CAST(ESSValue * 100 AS INT)
ELSE NULL
END as fieldname
For case expression the default is NULL if doesn't meet any condition, so you dont really need the ELSE condition
How to implement the scalar MAX in Sql server (like Math.Max). (In essense I want to implement something like Max(expression, 0), to make negative values replaced by 0.)
I've seen in other threads solutions with
creating a scalar function (how's that with performance?)
case when expression > 0 THEN expression ELSE 0) (then 'expression' is evaluated twice?)
complicated uses of
Max(aggregate).
What's the best?
Why does Sql Server not have something like this built in? Any complications I don't see?
In all other major systems this function is called GREATEST.
SQL Server seriously lacks it.
You can make a bunch of case statements, or use something like this:
SELECT (
SELECT MAX(expression)
FROM (
SELECT expression
UNION ALL
SELECT 0
) q
) AS greatest
FROM table_that_has_a_field_named_expression
The latter one is a trifle less performant than CASE statements.
you want to create a user-defined scalar function named MAX in sql server to take two parameters as input, an expression and a min value, and return the expression if it exceeds the min value, otherwise return the min value?
I wouldn't worry about the performance of scalar functions, let the server do that.
I'd also use IF instead of CASE to test for > min value.
SQL server doesn't have a built in function for you because they didn't think it would be widely enough used, I guess.
The query optimizer should prevent the expression from being calculated multiple times.
For readability / maintainability, consider using a CTE to calculate the expression before the CASE statement.