SQL CASE WHEN in WHERE clause - sql

searched for this problem, but couldn't find a question for exactly this problem.
I have a stored procedure that fetches data from a large amount of tables.
In my SP I have a parameter indicating the ID. Default Value of that ID is zero.
I want to return all values regarding this parameter in my query, unless a value is provided.
SELECT mT.*
FROM myTable mT
(various JOINS)
WHERE
CASE #myParameter
WHEN 0 THEN 1 = 1
ELSE mT.ID = #myParameter
END
Unfortunately I get the error message "Incorrect syntax near '='".
Things that are fixed: It has to be a SP, I get just one parameter where I can set a default value in case it is not filled. If it is not filled this part of the where clause shall not apply (there are more statements in the WHERE clause.
If I did not see a question that contained this problem please give me a hint where to find it.
Best Regards and thanks in advance!

You don't need CASE:
SELECT mT.*
FROM myTable mT
(various JOINS)
WHERE
#myParameter= 0 OR mT.ID = #myParameter

Related

Error with syntax replacing values in the query output

I work within the SQL database, but am self taught, so there are a few holes in my knowledge. I have this query that although I would think is simple, I just cant get it right.
I have two columns, one with a 'Name', and the other 'Privacy'.
I am trying to to get a result where if the Privacy column has a numerical value (3) in it, all these rows will return a 'name suppressed' in the Name column. And all the rows with a NULL in the Privacy column are left alone.
But I don't want to update the database, just suppress the name in the query.
I have tried, replace, case, if then and a few more with no luck. Can someone please help me.
Thanks
Michele
You can go for simple CASE expression. I am assuming you only want to suppress if privacy = 3.
SELECT CASE WHEN Privacy = 3 THEN 'Name Suppressed'
ELSE Name
END AS Name, Privacy
FROM TableName
SELECT
CASE
WHEN [Privacy] IS NULL THEN [Name]
ELSE N'name suppressed'
END AS [Name],
[Privacy]
FROM
[dbo].[YourTable]

Why Does One SQL Query Work and the Other Does Not?

Please disregard the obvious problems with the manipulation of data in the where clause. I know! I'm working on it. While working on it, though, I discovered that this query runs:
SELECT *
FROM PatientDistribution
WHERE InvoiceNumber LIKE'PEX%'
AND ISNUMERIC(CheckNumber) = 1
AND CONVERT(BIGINT,CheckNumber) <> TransactionId
And this one does not:
SELECT *
FROM PatientDistribution
WHERE InvoiceNumber LIKE'PEX%'
AND CONVERT(BIGINT,CheckNumber) <> TransactionId
AND ISNUMERIC(CheckNumber) = 1
The only difference between the two queries is the order of items in the WHERE clause. I was under the impression that the SQL Server query optimizer would take the worry out of me having to worry about that.
The error returned is: Error converting data type varchar to bigint.
You are right, the order of the conditions shouldn't matter.
If AND ISNUMERIC(CheckNumber) = 1 is checked first and non-matching rows thus dismissed, then AND CONVERT(BIGINT,CheckNumber) <> TransactionId will work (for exceptions see scsimon's answer).
If AND CONVERT(BIGINT,CheckNumber) <> TransactionId is processed before AND ISNUMERIC(CheckNumber) = 1 then you may get an error.
That your first query worked and the second not was a matter of luck. It could just as well have been vice versa.
You can force one condition to be executed before the other:
SELECT *
FROM
(
SELECT *
FROM PatientDistribution
WHERE InvoiceNumber LIKE 'PEX%'
AND ISNUMERIC(CheckNumber) = 1
) num_only
WHERE CONVERT(BIGINT,CheckNumber) <> TransactionId;
You just got lucky that the first one worked, since you are correct that the order of what you list in the where clause does not matter. SQL is a declarative language meaning that you are telling the engine what should happen, not how. So your queries weren't executed with the same query plan I would suspect. Granted, you can affect what the optimizer does to a certain extent. You'll also notice this type of issue when using a CTE. For example:
declare #table table(columnName varchar(64))
insert into #table
values
('1')
,('1e4')
;with cte as(
select columnName
from #table
where isnumeric(columnName) = 1)
select
cast(columnName as decimal(32,16))
from cte
The above snippet you would assume that the second statement is ran on the results / subset from the CTE statement. However, you can't ensure this will happen and you could still get a type/conversion error on the second statement.
More importantly, you should know that ISNUMERIC() is largely misused. People often think that if it returns 1 then it could be converted to a decimal or int. But this isn't the case. It just checks that it's a valid numeric type. For example:
select
isnumeric('1e4')
,isnumeric('$')
,isnumeric('1,123,456')
As you can see, these evaluate to true, but would fail the conversion you put in your post.
Side note, your indexes are likely the reason why the first actually didn't error our.

Why am I getting Oracle "invalid number" on my query when I am doing no type conversion?

I have a website that creates this SQL for one of the backend database queries (simplifying it for the question)
Select *
from People
where Status = 'Active'
and GroupId = 103403
and (TeamName in ('TEAM1', 'TEAM2'))
and DELETED is NULL
and this works fine. I now need to add a few new team names, something like this
Select *
from People
where Status = 'Active'
and GroupId = 103403
and (TeamName in ('TEAM1', 'TEAM2','TEAM3', 'TEAM4'))
and DELETED is NULL
and i get this error:
ORA-01722: invalid number
what is weird is that it doesn't seem to be anything wrong with "TEAM3" or "TEAM4" as if i do this
Select *
from People
where Status = 'Active'
and GroupId = 103403
and (TeamName in ('TEAM3', 'TEAM4'))
and DELETED is NULL
it also works fine. So only when i have a certain number of teams in the "IN" condition is when it breaks.
Any suggestions for what the issue could be. When I google that Oracle error all I see if people that have some conversion logic in their SQL as the root cause due to data type mismatching but I don't have any conversion logic here.
I suspect that GroupId isn't a numeric column. And depending on your other conditions, the condition GroupId = 103403 is evaluated before or after the other conditions. If it's evaluated for a row that contains an invalid number in the GroupId column, then your query fails.
If my assumption is correct, the change the condition to:
GroupId = '10340'
BTW: Please post the real SQL code, the code you have run in your own tests. Your current code contains double quotes, which hardly works.

Issue with 'NOT IN' statement in SQL

Can anyone please point out what is wrong with the following SQL statement:
SELECT DiaryType
FROM tblDiaryTypes
WHERE DiaryType NOT IN (SELECT NextDiary
FROM tblActionLinks
WHERE HistoryType = 'Info Chased');
Now the nested SELECT statement currently returns NULL because there are initially no entries in tblActionLinks, and I am wondering if that is the issue.
The outer SELECT statement if executed on its own does return all the Diary Types from tblDiaryTypes as expected. But when I add the nested SELECT statement to exclusde certain values, then the overall SQL statement returns empty!
Does this have something to do withthe fact that tblActionLinks is currently empty? If so, how can I amend my SQL statement to handle that possibility.
For SQL SERVER (you didn't specified sql engine) try with:
SELECT ISNULL(NextDiary, 0) ...
When no rows found all value is null then it will return 0
Are you sure there are no entries currently in tblActionLinks? If there are no entries in tblActionLinks, then outer query should return all records
Does this have something to do withthe fact that tblActionLinks is currently empty?
Yes... NULL doesn't being handled so good in SQL, Comparing a value to NULL is undifned try give for null a flag value like -999:
SELECT DiaryType
FROM tblDiaryTypes
WHERE DiaryType NOT IN (SELECT NVL(NextDiary, -999) -- <===
FROM tblActionLinks
WHERE HistoryType = 'Info Chased');
NVL(NextDiary, -999) means that if NextDiary IS NULL, replace the value with -999
docs
I would rewrite your query the following way:
SELECT DiaryType
FROM tblDiaryTypes
WHERE NOT EXISTS (SELECT NextDiary
FROM tblActionLinks
WHERE HistoryType = 'Info Chased'
AND NextDiary = DiaryType)
This ensures proper behaviour irrespective of ANSI_NULLS setting and you don't have to worry about properly choosing the magic value returned by ISNULL(NextDiary, 0) (what if you have DiaryType equal to 0 in tblDiaryTypes?)

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