SQL procedure where clause to list records - sql

I have a stored procedure that will query and return records based on if items are available or not. That part is easy, Im simply passing in a variable to check where available is yes or no.
But what I want to know is how do I throw a everything clause in there (i.e available, not available, or everything)?
The where clause right now is
where availability = #availability
The values of availabitility are either 1 or 0, nothing else.

You can use NULL to represent everything.
WHERE (#availability IS NULL OR availability = #availability)

SELECT *
FROM mytable
WHERE #availability IS NULL
UNION ALL
SELECT *
FROM mytable
WHERE availability = #availability
Passing a NULL value will select everything.
This query will use an index on availability if any.

Don't know the type of #availability, but assuming -1 = everything then you could simply do a
where #availability = -1 OR availability = #availability

multiple ways of doing it. Simpliest way is is to set the default value of the #availability to null and then your where clause would look like this
WHERE (#availability IS NULL OR availability = #availability)

Related

Ignore other results if a resultset has been found

To start, take this snippet as an example:
SELECT *
FROM StatsVehicle
WHERE ((ReferenceMakeId = #referenceMakeId)
OR #referenceMakeId IS NULL)
This will fetch and filter the records if the variable #referenceMakeId is not null, and if it is null, will fetch all the records. In other words, it is taking the first one into consideration if #referenceMakeId is not null.
I would like to add a further restriction to this, how can I achieve this?
For instance
(ReferenceModelId = #referenceModeleId) OR
(
(ReferenceMakeId = #referenceMakeId) OR
(#referenceMakeId IS NULL)
)
If #referenceModelId is not null, it will only need to filter by ReferenceModelId, and ignore the other statements inside it. If I actually do this as such, it returns all the records. Is there anything that can be done to achieve such a thing?
Maybe something like this?
SELECT * FROM StatsVehicle WHERE
(
-- Removed the following, as it's not clear if this is beneficial
-- (#referenceModeleId IS NOT NULL) AND
(ReferenceModelId = #referenceModeleId)
) OR
(#referenceModeleId IS NULL AND
(
(ReferenceMakeId = #referenceMakeId) OR
(#referenceMakeId IS NULL)
)
)
This should do the trick.
SELECT * FROM StatsVehicle
WHERE ReferenceModelId = #referenceModeleId OR
(
#referenceModeleId IS NULL AND
(
#referenceMakeId IS NULL OR
ReferenceMakeId = #referenceMakeId
)
)
However, you should note that this types of queries (known as catch-all queries) tend to be less efficient then writing a single query for every case.
This is due to the fact that SQL Server will cache the first query plan that might not be optimal for other parameters.
You might want to consider using the OPTION (RECOMPILE) query hint, or braking down the stored procedure to pieces that will each handle the specific conditions (i.e one select for null variables, one select for non-null).
For more information, read this article.
If #referenceModelId is not null, it will only need to filter by
ReferenceModelId, and ignore the other statements inside it. If I
actually do this as such, it returns all the records. Is there
anything that can be done to achieve such a thing?
You can think of using a CASE for good short circuit mechanism
WHERE
CASE
WHEN #referenceModelId is not null AND ReferenceModelId = #referenceModeleId THEN 1
WHEN #referenceMakeId is not null AND ReferenceMakeId = #referenceMakeId THEN 1
WHEN #referenceModelId is null AND #referenceMakeId is null THEN 1
ELSE 0
END = 1

sql server if statement not working

Can anyone advise me as to what is wrong with the following SQL server update statement:
IF (SELECT * FROM TBL_SystemParameter WHERE code='SOUND_WRONG_GARMENT') = ''
GO
UPDATE TBL_SystemParameter
SET [Value] = 'Ping.wav'
WHERE ID = (SELECT ID
FROM TBL_SystemParameter
WHERE code = 'SOUND_WRONG_GARMENT')
You don't need an if statement - you can just run the update statement, and if the subquery returns no rows, no rows will be updated. The if won't really save anything - you're performing two queries instead of one.
You either want
UPDATE TBL_SystemParameter
SET [Value] = 'Ping.wav'
WHERE ID In (SELECT ID
FROM TBL_SystemParameter
WHERE code = 'SOUND_WRONG_GARMENT')
if there are multiple ID's with that code OR use
UPDATE TBL_SystemParameter
SET [Value] = 'Ping.wav'
WHERE code = 'SOUND_WRONG_GARMENT'
either way and lose the IF statement as #Mureinik said.
Although Mureinik's answer is the logical solution to this, I will answer why this isn't actually working. Your condition is wrong, and this approach will work instead using IF EXISTS:
IF EXISTS (SELECT * FROM TBL_SystemParameter WHERE code='SOUND_WRONG_GARMENT')
BEGIN
UPDATE TBL_SystemParameter
SET [Value] = 'Ping.wav'
WHERE ID IN (SELECT ID
FROM TBL_SystemParameter
WHERE code = 'SOUND_WRONG_GARMENT')
END
As a side note, you're using an = sign instead of IN, which means you'll be matching to an arbitrary singular ID and only update 1 row based on this. To use a set based operation, use the IN clause.
You could actually 'golf' this by doing away with the derived query altogether, and using a simple WHERE code='SOUND_WRONG_GARMENT' on the table you're updating on.

Checking tables for null returns 0 regardless

I don't understand why this query doesn't work.
I have a table which is full of rows where 3 of the column values are set to NULL.
But when I run the following query, it returns 0 (it should return 96)
SELECT COUNT(*) FROM SEAT WHERE BOOKED=null;
Do you know what I am doing wrong?
It depends on your database settings and the specific RDBMS you are using, but if you are using ANSI NULL syntax you cannot directly compare a value to NULL with an equality test (=) -- it will always fail.
Use WHERE BOOKED IS NULL instead.
You have to use IS NULL instead of = null
Since null technically isn't a value, you can't compare null using the = operator.
Use IS NULL
SELECT COUNT(*)
FROM SEAT
WHERE BOOKED IS NULL

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?)

How to select an empty result set?

Want to improve this post? Provide detailed answers to this question, including citations and an explanation of why your answer is correct. Answers without enough detail may be edited or deleted.
I'm using a stored procedure in MySQL, with a CASE statement.
In the ELSE clause of the CASE ( equivalent to default: ) I want to select and return an empty result set, thus avoiding to throw an SQL error by not handling the ELSE case, and instead return an empty result set as if a regular query would have returned no rows.
So far I've managed to do so using something like:
Select NULL From users Where False
But I have to name an existing table, like 'users' in this example.
It works, but I would prefer a way that doesn't break if eventually the table name used is renamed or dropped.
I've tried Select NULL Where False but it doesn't work.
Using Select NULL does not return an empty set, but one row with a column named NULL and with a NULL value.
There's a dummy-table in MySQL called 'dual', which you should be able to use.
select
1
from
dual
where
false
This will always give you an empty result.
This should work on most DBs, tested on Postgres and Netezza:
SELECT NULL LIMIT 0;
T-SQL (MSSQL):
SELECT Top 0 1;
How about
SELECT * FROM (SELECT 1) AS TBL WHERE 2=3
Checked in myphp, and it also works in sqlite and probably in any other db engine.
This will probably work across all databases.
SELECT * FROM (SELECT NULL AS col0) AS inner0 WHERE col0 IS NOT NULL;
SELECT TOP 0 * FROM [dbo].[TableName]
This is a reasonable approach to constant scan operator.
SELECT NULL WHERE FALSE;
it works in postgresql ,mysql, subquery in mysql.
How about this?
SELECT 'MyName' AS EmptyColumn
FROM dual
WHERE 'Me' = 'Funny'
SELECT * FROM (SELECT NULL) WHERE 0
In PostgreSQL a simple
SELECT;
works. You won't even get any columns labeled 'unknown'.
Note however, it still says 1 row retrieved.