SQL Statement with CASE when there are no values - sql

I am trying to use CASE statement for the following, however it is not getting desired results.
What I would like to have is if there are no values based on where condition, then I would like to return 'N' as the result.
SELECT CASE WHEN val IS NULL THEN 'N' else val END
from (select nvl(is_expired,'x')val
FROM test
WHERE product_no = '12DF')
When product_no 12DF doesn't exist in table, I would like to return a value instead of empty or null.
Table structure is specified here

If there are no products '12DF', then you won't get any lines from your subselect.
I'm not quite sure which problem you want to solve.
If you have embedded this in a program, because you can get a result set containing more than one row, that code should be able to handle an empty set as well.
If you expect zero or one lines in your result set, you can use an aggregate function like max.
select nvl(max(is_expired), 'N')
from test
where product_no = '12DF';

Related

How to return a null column using NOT IN () in SQL

I want to return some data using the following query.
select *
from table
where code_value not in ('44','45','46')
This statement return all expected rows except rows with code_value = null.
I want to get the null columns also.
How can I get that?
Use IS NULL :
WHERE (code_value IS NULL OR code_value not in ('44','45','46'));
NOT IN will not return records when compared against an unknown value or NULL values.
The direct comparison to NULL is the right solution. But I offer this to illustrate the "inverse" of IN. It is more like:
select t.*
from t
except
select t.*
from t
where code_value not in ('44', '45', '46');
Than not in. This is not even exact either, because except removes duplicates. But it is logically closer to the inverse.
I would do it using isnull in conjunction with a default value which doesn't exist in the code_value;
select *
from table
where isnull(code_value,'<<non existing value>>') not in ('44','45','46')

Oracle Coalesce returns blank

I have following query which uses coalesce to return the id of a calendar with a specific code
SELECT COALESCE(SD_CALENDAR.ID,0) FROM SD_CALENDAR WHERE SD_CALENDAR.CODE = 'BOER';
But when I run this I get a blank column as result, instead of 0. What do I need to change to make my query work?
You said that no rows in your table match your query, so you are trying to return 0 when there is no match, rather than returning no data at all.
If NAME is unique then you could use an aggregate to achieve this:
SELECT COALESCE(MAX(SD_CALENDAR.ID),0) FROM SD_CALENDAR WHERE SD_CALENDAR.CODE = 'BOER';
The MAX() will always return one row; if there is a match it will be the single ID anyway, and if there isn't it will be null - which you can then coalesce to zero.
If NAME isn't unique and you expect multiple values back then you can use a union to provide the zero value when there is no match:
SELECT COALESCE(SD_CALENDAR.ID,0) FROM SD_CALENDAR WHERE SD_CALENDAR.CODE = 'BOER'
UNION ALL
SELECT 0 FROM DUAL WHERE NOT EXISTS (
SELECT COALESCE(SD_CALENDAR.ID,0) FROM SD_CALENDAR WHERE SD_CALENDAR.CODE = 'BOER'
);
Depending on what you're doing, it might be better/easier to let your application handle a no-data-found result and substitute a zero itself.

Selecting from table to insert into another, getting a type error

I have the following query which inserts data into one table after selecting it from another.
The problem is that the data types do not match for one of the columns. I have simplified the query below.
INSERT INTO tbl.LogTable (
[SelPartNo], -- This does not match, see below
)
SELECT TOP 1
IF([SelPartNo] = 'False', NULL, [SelPartNo],
FROM tbl.MyTable
WHERE ID = '20358'
ORDER BY CreateDate DESC
The first SelPartNo is an int and the second is a VarChar. In most instances the SelPartNo for the second one (tbl.MyTable) is NULL or an integer, which I don't think will cause a problem. But in some cases the value is "False", which needs to return NULL.
I have tried an IF statement but I am doing something wrong because it's giving a syntax error and I am unsure if this is the correct approach.
Your code is syntactically incorect...
Try it with
NULLIF([SelPartNo],'False')
This function returns NULL if the two expressions are equal.
Details: https://msdn.microsoft.com/en-us/library/ms177562.aspx
I don't think IF is a function, at least not one which you can use in a SELECT statement. But CASE WHEN ... END is your friend:
INSERT INTO tbl.LogTable (
[SelPartNo]
)
SELECT TOP 1
CASE WHEN [SelPartNo] = 'False' THEN NULL ELSE [SelPartNo] END
FROM tbl.MyTable
WHERE ID = '20358'
ORDER BY CreateDate DESC

Replace value in result by a specific value

I need to make a query to collect some data from a database via SQL. In this data there is 1 value used as collection value. This are ID's of courses given. Sometimes a course can be given about f.e. Office. But people can do a course there for word, excel, powerpoint... But this is all given in 1 course by 1 tutor. Still for statistics I need to know if they participated the course for Word, Excel, Powerpoint ...
Is it possible to replace values in the resultset? With this i mean something like this:
if value = courseValue ==> replace value with specific courseValue (I can get the value via a subquery)
I hope this makes my problem clear and i appriciate all the help!
You can use a case statement in your select to return something other than the course id that is on the row. For example:
SELECT
field1 AS 'Name',
CASE
WHEN field2 = 'Foo'
THEN 'Bar'
WHEN field2 = 'Lorem'
THEN 'Ipsum'
ELSE 'Some Value'
END
AS 'Type',
field3 AS 'Description'
FROM table
If I understand you correctly, you will need something along the lines of this:
Create a new table with "courseID" and "replacementID" columns, fill it for the cases where there is a replacement
In your query do an outer join with this table over the courseID fields and also return the "replacementID", which can be null is there is no replacement
Use either the replacementID if it isn't null or the courseID

SQL Case statement returning true although should be false

I have a SQL statement that is something like this
SELECT t1.*
CASE
WHEN t1.COL1 = 0 THEN 0
WHEN
(t1.COL2 = 'val' OR t1.COL3 = 'val' etc) AND ((SELECT COUNT(*) FROM t1 WHERE etc...) > 0)
THEN Run same sub query
WHEN
something else
THEN defaultvalue
END as brokencase
Now, the second WHEN statement above, when run alone, is returning zero. However when it is run here, I am getting a bunch of null values back because that statement is somehow returning true.
So why is the count statement returning zero, but the WHEN statement thinks its true? I have left out a lot of details here for privacy reasons, but this is the general problem.
Usually when I see this, the programmer is missing an ELSE or DEFAULT case in their statements. To find out what scenario you're not capturing, set up a select like this:
SELECT DISTINCT columnTested1, columnTested2, columnTestedX, case statement
FROM blah
Show all the columns being tested, then your case, what you'll see in the result is the combination of columns that are causing your NULL. You need to capture those in your case statement or you'll continue to miss those options
When you test different columns in the different options, you might need multiple else statements to catch them all. Once you've identified the combination of columns causing you a problem, it becomes dead simple to fix the case statement.
If you want to exclude results that have null values you will have to make sure you are checking for that in your WHEN condition. You haven't specified your WHERE clause in your count query so I can't say for sure if this is the problem. It would look something like this:
SELECT COUNT(*) FROM t1 WHERE ExcludeValue IS NOT NULL