Select the result of a comparison in SQL statement - sql

How would I achieve the following:
select (1 < 2) as One, (1 > 2) as Two
so that it would yield the following results:
One Two
-----------------
True False
I'm using SQL Server but a cross DBMS example would be good.

Assuming this is SQL server, you can use CASE statement.
select (case when (1 < 2) then 'True' else 'False' end) as one,
(case when (1 > 2) then 'True' else 'False' end) as two
from table
In the place of condition, you can use any variable or any column values too. Basically an expression.

Well, in Oracle you could do something like
SELECT CASE
WHEN 1 < 2 THEN
'TRUE'
ELSE
'FALSE'
END AS ONE,
CASE
WHEN 1 > 2 THEN
'TRUE'
ELSE
'FALSE'
END AS TWO
FROM DUAL;
Note that Oracle doesn't have a BOOLEAN type in the database (as opposed to PL/SQL, which does have BOOLEAN's) so the case expressions return character strings.
Share and enjoy.

Use a case statement:
declare #value1 int, #value2 int
set #value1 = 1
set #value2 = 2
select
case when (#value1 < #value2) then 'True' else 'False' end as One
case when (#value1 > #value2) then 'False' else 'True' end as Two
from table
Depending on your need, you can hard code in the values, or you can do something similar to this for when you may want to change the values. You could also combine the case statement into one column, or break it out for doing less than or equal type comparisons as well.

Related

SQL: CASE expression with declared variable

I have following example that doesn't work in SQL server.
table1.field1 is also a char(3)
DECLARE #CALCULATED_FIELD char(3);
SELECT table1.field1
,table1.field2
,CASE
WHEN table1.field2 = '1' THEN #CALCULATED_FIELD = table1.field1
ELSE #CALCULATED_FIELD = 'ALL'
END
FROM table1
Anyone knows the problem with the case statement?
A SQL Server SELECT statement can either assign variable values or return rows, but not both. You might intend:
SELECT #CALCULATED_FIELD = COALESCE(table1.field1, 'ALL')
FROM table1;
This would assign the maximum value to the variable -- and the only value if the table has only one row. If the table has no rows, the variable would be assigned 'ALL'.
The result of the CASE expression must be assigned to the variable, but it is not allowed in the same statement to return any columns from the table.
So this:
SELECT
#CALCULATED_FIELD = CASE
WHEN field2 = '1' THEN field1
ELSE 'ALL'
END
FROM table1
is syntactically valid, although it will assign to the variable finally, the result of the CASE expression of the last row fetched.
By the name of the variable, I suspect that you want a 3d column which will be calculated by CASE:
SELECT field1, field2,
CASE
WHEN field2 = '1' THEN field1
ELSE 'ALL'
END calculated_field
FROM table1
See a simplified demo.
I would use a scaler funtion in this case
CREATE FUNCTION calcfield
(
#field2 VARCHAR(4),
#field1 VARCHAR(4)
)
RETURNS VARCHAR(3)
AS
BEGIN
DECLARE #CalcField CHAR(3)
SELECT #CalcField = CASE
WHEN #field2 = '1' THEN #field1
ELSE 'ALL'
END
RETURN #CalcField
END
GO
and then change your query to
SELECT table1.field1
,table1.field2
,dbo.calcfield(table1.field2,table1.field1)
FROM table1
Expressions like A=B is not a scalar value. So when you run the following query, it fails and you will get an error Incorrect syntax near '='.
SELECT ('aaa' = 'aaa')
In your case
CASE WHEN table1.field2 = '1'
THEN #CALCULATED_FIELD = table1.field1
ELSE #CALCULATED_FIELD = 'ALL'
END
is not a valid expression, and you might mean something like
CASE WHEN table1.field2 = '1'
THEN (CASE WHEN #CALCULATED_FIELD = table1.field1 THEN 1 ELSE 0)
ELSE (CASE WHEN #CALCULATED_FIELD = 'ALL' THEN 1 ELSE 0)
END
Please note that you can run a query like
SELECT columnName = 'aaa'
and it works as
SELECT 'aaa' AS columnName
Thx a lot.
For the create function, I have no rights and we can't do it on the production environment. But would work. Nice.
The example from forpas used and it works perfect for me.

Choose multiple cases condition

I want to get multipule choises after then in case statment as
#value
select * from [dbo].[Currency_Tbl]
WHERE [Currency_Active_YN]=
CASE WHEN #value = 1 THEN
( 1 or 0)
ELSE
#Value = 0 then 0
END
it didn't accept the first line in col1 but accept the col2
how can I select multiple numbers after THEN?
You don't use case in where clauses. Use boolean logic
select * from [dbo].[Currency_Tbl]
WHERE (#value = 1 and [Currency_Active_YN] in (0,1))
OR (#value = 0 and [Currency_Active_YN] = 0)
You dont need a case to do what you're trying to do. Assuming Currency_Active_YN is a not null bit field the following logic should suffice.
select * from [dbo].[Currency_Tbl]
WHERE (#value=1 OR [Currency_Active_YN]=#Value)

How to compare two columns in the CASE statement

I have two columns Speed_A and Speed_B.
Now I will compare both columns and will select the higher one in a new table.
Something like this:
SELECT ...
CASE
WHEN a.Speed_A > a.Speed_B THEN a.Speed_A
WHEN a.Speed_A < a.Speed_B THEN a.Speed_B
ELSE 0 --unknown
END as SpeedLimit,
How does it work?
Assuming your speeds are numerically typed you might get this as easy as:
SELECT CASE WHEN a.Speed_A>a.Speed_B THEN a.Speed_A ELSE a.Speed_B END AS SpeedLimit
[...FROM SomeWhere...]
Your ELSE will only occur, when A and B are equal, In this case it doesn't matter, which one you return.
UPDATE
columnĀ“s data type is integer. And yes there are nulls
If A is null return B, If b is null return A (works for A and B is null implicitly). Otherwise both are not null and therefore the statement above should be perfect
SELECT CASE WHEN a.Speed_A IS NULL THEN a.Speed_B
ELSE CASE WHEN a.Speed_B IS NULL THEN a.Speed_A
ELSE CASE WHEN a.Speed_A>a.Speed_B THEN a.Speed_A ELSE a.Speed_B
END
END
END AS SpeedLimit
FROM Dummy
[...FROM SomeWhere...]
You can create a inline max function that return the max between two values something like:
create function dbo.InlineMax(#val1 int, #val2 int)
returns int
as
begin
if #val1 > #val2
return #val1
return isnull(#val2,#val1)
end
and you can use it like this:
SELECT dbo.InlineMax(a.Speed_A, a.Speed_B)
FROM ....
Nested Case and Case without Column Name
select
CASE ColumnName
WHEN 'enter value on which you want to execute Than Block'
THEN
CASE ColumnName
WHEN 1 THEN 'return value or Column Name'
ELSE 'return value or Column Name in case of else'
END
WHEN 'another condition, value of column on which you want to execute then block'
THEN
CASE WHEN 'Condition etc => ColumnName > 5 or ColumnName ='abc' ' THEN 'return value or column name' ELSE 'return value or column name' END
ELSE 'return value or column name'
END as status
FROM TableName

Nested Case Then in SQL

I'm trying to do the following which involves a complex query;
1. First I try to select the column based on some logic
2. then based on the value of the selected column a value is selected
3. finally based on the previous value a logic is applied to get the final value
How can I have the result from 2 in the ELSE of the 3rd Case..Then statement ?
CASE
CASE
CASE
WHEN MDC.Network ='I' THEN INNBenefitID ELSE OONBenefitID
END
WHEN 'INNDWO' THEN CASE WHEN DWO.Description IS NOT NULL THEN DWO.Description ELSE MDC.CostShareValue END
WHEN 'OONDWO' THEN CASE WHEN DWO.Description IS NOT NULL THEN DWO.Description ELSE MDC.CostShareValue END
ELSE isnull(dbo.fn_FormatText(MDC.CostShareValue, CostShareType),'''')
END
WHEN '0%' THEN 'Covered 100%'
WHEN '$0' THEN 'Covered 100%'
ELSE ????
END
Are you looking for something like that? :
declare #value varchar(255) = (
CASE
WHEN MDC.Network ='I' THEN INNBenefitID ELSE OONBenefitID
WHEN 'INNDWO' THEN CASE WHEN DWO.Description IS NOT NULL THEN DWO.Description ELSE MDC.CostShareValue
WHEN 'OONDWO' THEN CASE WHEN DWO.Description IS NOT NULL THEN DWO.Description ELSE MDC.CostShareValue
ELSE isnull(dbo.fn_FormatText(MDC.CostShareValue, CostShareType),'''')
END
)
CASE
WHEN '0%' THEN 'Covered 100%'
WHEN '$0' THEN 'Covered 100%'
ELSE #value
END
Really, really hard to do this right without a schema or sample data. In the future consider creating a SqlFiddle for us. But one approach you might consider is using a Common Table Expression (CTE) to define an intermediary structure which you then query.
;WITH theCTE AS (SELECT
CASE
CASE
WHEN MDC.Network ='I' THEN INNBenefitID ELSE OONBenefitID
END
WHEN 'INNDWO' THEN COALESCE(DWO.Description, MDC.CostShareValue)
WHEN 'OONDWO' THEN COALESCE(DWO.Description, MDC.CostShareValue)
ELSE COALESCE(dbo.fn_FormatText(MDC.CostShareValue, CostShareType), '')
END AS foo
FROM
bar
)
SELECT
CASE
WHEN foo IN ('0%', '$0') THEN 'Covered 100%'
ELSE '' -- Do something with foo --
END AS finalColumn
FROM
theCTE

Change aggregate functions to output NULL when a element is NULL

Every question I search for about the warning
Warning: Null value is eliminated by an aggregate or other SET operation.
Typically people want to treat the NULL values as 0. I want the opposite, how do I modify the following stored procedure to make it return NULL instead of 1?
CREATE PROCEDURE TestProcedure
AS
BEGIN
select cast(null as int) as foo into #tmp
insert into #tmp values (1)
select sum(foo) from #tmp
END
GO
I thought it would be SET ANSI_NULLS ON (I tried before the declaration, within the procedure itself, and before executing the procedure in my test query) but that did not appear to change the behavior of SUM(.
The sum() function automatically ignores NULL. To do what you want, you need an explicit checK:
select (case when count(foo) = count(*) then sum(foo) end)
from #tmp;
If you want to be explicit, you could add else NULL to the case statement.
The logic behind this is that count(foo) counts the number of non-NULL values in foo. If this is equal to all the rows, then all the values are non-NULL. You could use the more verbose:
select (case when sum(case when foo is null then 1 else 0 end) > 0
then sum(foo)
end)
And, I want to point out that the title is quite misleading. 1 + NULL = NULL. The issue is with the aggregation functions, not the arithmetic operators.
Looking for a null value with EXISTS may be the fastest:
SELECT
CASE WHEN EXISTS(SELECT NULL FROM tmp WHERE foo IS NULL)
THEN NULL
ELSE (SELECT sum(foo) from tmp)
END
Just say
select case sign(sum(case when foo is null then 1 else 0 end))
when 1 then null
else sum(foo)
end
from some_table
...
group by
...
That's about all you need.