use 'case when' after in function - sql

I need to use case when to generate the value range for in function (in DB2).
for example, in below code, I want the columnB in (5,6)
select columnA from tableName where columnB in (
(case
when #variable=1 then '4' // specific number
when #variable=2 then '5' //specific number
when #variable=3 then '7,10' // a value range
end)
)
but tried several times and other similar solutions, never got the expected result
how to do this?

Firstly, In function does not read multiple values inside Case statement. The comma must be after every single value in the range.
Second, you can mention a valid condition in your Question, rather than just 1=1. It's always true so, doesn't make sense.
Example:
1) output of below query gives in (5, 6)
select columnA from tableName where columnB in ((case when #variable=1 then 5 end), 6);
2) this gives only records of columnB = 5, let say the second condition is false.
select columnA from tableName where columnB in ((case when #variable=1 then 5 end), (case when #variable=2 then 6 end));

try Something like this
select columnA from tableName
where columnB in (
select * from table(values 4) tmp(NewCol)
where #variable=1
union all
select * from table(values 5) tmp(NewCol)
where #variable=2
union all
select * from table(values 7, 10) tmp(NewCol)
where #variable=3
)

You cannot have string as value range unless you convert it into rowset. I'm not sure how to do this in DB2, but I have something that should work, since according to documentation, DB2 does have unnest(). There are of course other ways to create rowsets.
SELECT columnA
FROM unnest(array[2,6,8,10], array[7,5,6,28]) --create "temp table" for example purposes
WITH ORDINALITY AS a(columnA, columnB) --alias columns from temp table
WHERE
CASE WHEN true THEN --switch true to some other condition
columnB IN(SELECT * FROM unnest(array[5,6])) --unnest(array[]) will create rowset with 2 rows, each having one column holding integer value
END;
You might need to drop alias from AS a(columnA, columnB) since I'm not sure if it works in DB2 and I have not found live DB2 tester (it is required in PostgreSQL where I tested query).

Related

SQL select statement to change two other column values based on a column that contains null

I would like to use a SQL select statement that has the condition 'where column A is NULL change column B values to be equal to column C values'. How would I be able to incorporate this logic into a SELECT statement (Not an UPDATE statement as I cant change the tables on the server but want to query them from the server).
SELECT final.*
FROM final
The actual table is in the image below, here I want to change column Old to match column DirectUse if the Change column is null.
Try Case statement:
SELECT
Name, NameSimple, DirectUse, Year, Month,
CASE WHEN Change IS NULL THEN DirectUse ELSE Old END AS Old,
CurrentCons, Change
FROM final;
CASE: https://www.w3schools.com/sql/sql_case.asp
Can also be incorporated by UNION ALL:
SELECT Old
FROM final where Change is not null
UNION ALL
SELECT DirectUse
FROM final where Change is null
Use a CASE expression:
SELECT Name, NameSimple, DirectUse, Year, Month,
CASE WHEN Change IS NULL THEN DirectUse ELSE Old END AS Old,
CurrentCons, Change
FROM final;
I think you basically you want:
SELECT
ColumnA
, CASE WHEN ColumnA IS NULL THEN ColumnC ELSE ColumnB END AS ColumnB
, ColumnC
, <any other columns>
FROM Final

Set range of numbers for IN statement

I am trying to set a specific range of numbers for an IN clause in SQL Server for example, if the values of 1 - 100 are in column A, then do this...etc. My example below of what I am trying to do:
SELECT
CASE WHEN (values of 1 to 100) IN (columnA) THEN columnB
ELSE ...
END AS [column]
FROM table
Is this possible what I am trying to do within SQL Server?
Yes, the syntax would be:
SELECT
CASE WHEN columnA BETWEEN 1 AND 100 THEN columnB
ELSE ...
END AS [column]
FROM table
See the documentation on CASE statements here.

Why can't i refer to a column alias in the ORDER BY using CASE?

Sorry if this a duplicate, but i haven't found one. Why can't i use my column alias defined in the SELECT from the ORDER BY when i use CASE?
Consider this simple query:
SELECT NewValue=CASE WHEN Value IS NULL THEN '<Null-Value>' ELSE Value END
FROM dbo.TableA
ORDER BY CASE WHEN NewValue='<Null-Value>' THEN 1 ELSE 0 END
The result is an error:
Invalid column name 'NewValue'
Here's a sql-fiddle. (Replace the ORDER BY NewValue with the CASE WHEN... that´'s commented out)
I know i can use ORDER BY CASE WHEN Value IS NULL THEN 1 ELSE 0 END like here in this case but actually the query is more complex and i want to keep it as readable as possible. Do i have to use a sub-query or CTE instead, if so why is that so?
Update as Mikael Eriksson has commented any expression in combination with an alias is not allowed. So even this (pointless query) fails for the same reason:
SELECT '' As Empty
FROM dbo.TableA
ORDER BY Empty + ''
Result:
Invalid column name 'Empty'.
So an alias is allowed in an ORDER BY and also an expression but not both. Why, is it too difficult to implement? Since i'm mainly a programmer i think of aliases as variables which could simple be used in an expression.
This has to do with how a SQL dbms resolves ambiguous names.
I haven't yet tracked down this behavior in the SQL standards, but it seems to be consistent across platforms. Here's what's happening.
create table test (
col_1 integer,
col_2 integer
);
insert into test (col_1, col_2) values
(1, 3),
(2, 2),
(3, 1);
Alias "col_1" as "col_2", and use the alias in the ORDER BY clause. The dbms resolves "col_2" in the ORDER BY as an alias for "col_1", and sorts by the values in "test"."col_1".
select col_1 as col_2
from test
order by col_2;
col_2
--
1
2
3
Again, alias "col_1" as "col_2", but use an expression in the ORDER BY clause. The dbms resolves "col_2" not as an alias for "col_1", but as the column "test"."col_2". It sorts by the values in "test"."col_2".
select col_1 as col_2
from test
order by (col_2 || '');
col_2
--
3
2
1
So in your case, your query fails because the dbms wants to resolve "NewValue" in the expression as a column name in a base table. But it's not; it's a column alias.
PostgreSQL
This behavior is documented in PostgreSQL in the section Sorting Rows. Their stated rationale is to reduce ambiguity.
Note that an output column name has to stand alone, that is, it cannot be used in an expression — for example, this is not correct:
SELECT a + b AS sum, c FROM table1 ORDER BY sum + c; -- wrong
This restriction is made to reduce ambiguity. There is still ambiguity if an ORDER BY item is a simple name that could match either an output column name or a column from the table expression. The output column is used in such cases. This would only cause confusion if you use AS to rename an output column to match some other table column's name.
Documentation error in SQL Server 2008
A slightly different issue with respect to aliases in the ORDER BY clause.
If column names are aliased in the SELECT list, only the alias name can be used in the ORDER BY clause.
Unless I'm insufficiently caffeinated, that's not true at all. This statement sorts by "test"."col_1" in both SQL Server 2008 and SQL Server 2012.
select col_1 as col_2
from test
order by col_1;
It seems this limitation is related to another limitation in which "column aliases can't be referenced in same SELECT list". For example, this query:
SELECT Col1 AS ColAlias1 FROM T ORDER BY ColAlias1
Can be translated to:
SELECT Col1 AS ColAlias1 FROM T ORDER BY 1
Which is a legal query. But this query:
SELECT Col1 AS ColAlias1 FROM T ORDER BY ColAlias1 + ' '
Should be translated to:
SELECT Col1 AS ColAlias1, ColAlias1 + ' ' FROM T ORDER BY 2
Which will raise the error:
Unknown column 'ColAlias1' in 'field list'
And finally it seems these are because of SQL standard behaviours not an impossibility in implementation.
More info at: Here
Note: The last query can be executed by MS Access without error but will raise the mentioned error with SQL Server.
You could try something like:
select NewValue from (
SELECT (CASE WHEN Value IS NULL THEN '<Null-Value>' ELSE Value END ) as NewValue,
( CASE WHEN NewValue='<Null-Value>' THEN 1 ELSE 0 END) as ValOrder
FROM dbo.TableA
GROUP BY Value
) t
ORDER BY ValOrder

How to assign a value to a casted column in Oracle

I am wondering whether is possible to assign a value to a casted column in SQL depending on real table values.
For Example:
select *, cast(null as number) as value from table1
where if(table1.id > 10 then value = 1) else value = 0
NOTE: I understand the above example is not completely Oracle, but, it is just a demonstration on what I want to accomplish in Oracle. Also, the above example can be done multiple ways due to its simplicity. My goal here is to verify if it is possible to accomplish the example using casted columns (columns not part of table1) and some sort of if/else.
Thanks,
Y_Y
select table1.*, (case when table1.id > 10 then 1 else 0 end) as value
from table1

Select rows where column is null

How do you write a SELECT statement that only returns rows where the value for a certain column is null?
Do you mean something like:
SELECT COLUMN1, COLUMN2 FROM MY_TABLE WHERE COLUMN1 = 'Value' OR COLUMN1 IS NULL
?
I'm not sure if this answers your question, but using the IS NULL construct, you can test whether any given scalar expression is NULL:
SELECT * FROM customers WHERE first_name IS NULL
On MS SQL Server, the ISNULL() function returns the first argument if it's not NULL, otherwise it returns the second. You can effectively use this to make sure a query always yields a value instead of NULL, e.g.:
SELECT ISNULL(column1, 'No value found') FROM mytable WHERE column2 = 23
Other DBMSes have similar functionality available.
If you want to know whether a column can be null (i.e., is defined to be nullable), without querying for actual data, you should look into information_schema.
Use Is Null
select * from tblName where clmnName is null
You want to know if the column is null
select * from foo where bar is null
If you want to check for some value not equal to something and the column also contains null values you will not get the columns with null in it
does not work:
select * from foo where bar <> 'value'
does work:
select * from foo where bar <> 'value' or bar is null
in Oracle (don't know on other DBMS) some people use this
select * from foo where NVL(bar,'n/a') <> 'value'
if I read the answer from tdammers correctly then in MS SQL Server this is like that
select * from foo where ISNULL(bar,'n/a') <> 'value'
in my opinion it is a bit of a hack and the moment 'value' becomes a variable the statement tends to become buggy if the variable contains 'n/a'.
select Column from Table where Column is null;
select * from tableName where columnName is null
For some reasons IS NULL may not work with some column data type. I was in need to get all the employees that their English full name is missing, I've used:
SELECT emp_id, Full_Name_Ar, Full_Name_En
FROM employees
WHERE Full_Name_En = '' or Full_Name_En is null