Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SQL: Return "true" if list of records exists?

An alternative title might be: Check for existence of multiple rows?

Using a combination of SQL and C# I want a method to return true if all products in a list exist in a table. If it can be done all in SQL that would be preferable. I have written a method that returns whether a single productID exists using the following SQL:

SELECT productID FROM Products WHERE ProductID = @productID

If this returns a row, then the c# method returns true, false otherwise.

Now I'm wondering if I have a list of product IDs (not a huge list mind you, normally under 20). How can I write a query that will return a row if all the product id's exist and no row if one or more product id's does not exist?

(Maybe something involving "IN" like:
SELECT * FROM Products WHERE ProductID IN ('1', '10', '100', 'ABC'))

EDIT:

How the result is expressed is not important to me. Whether the query returns a 1 or 0, an empty resultset or a non-empty one, true or false doesn't matter. I'd prefer the answer that is 1) easy to read and understand and 2) performant

I was envisioning concatenating the list of product id's with the SQL. Obviously this opens the code up to SQL injection (the product id's are actually varchar. in this case the chance is slim but still want to avoid that possibility). So if there is a way around this that would be better. Using SQL Server 2005.

Product ID's are varchar

like image 980
User Avatar asked May 19 '10 00:05

User


People also ask

Can SQL return Boolean?

SQL Server does not support a Boolean type e.g. SELECT WHEN CAST(1 AS BIT) THEN 'YES' END AS result -- results in an error i.e. CAST(1 AS BIT) is not the same logical TRUE.

Can I use if exists in SQL?

It works fine if the object exists in the database. In case the object does not exist, and you try to drop, you get the following error. To avoid this situation, usually, developers add T-SQL If Exists statement and drop the object if it is already available in the database.

How do you use exists instead of in in SQL Server?

Using Joins Instead of IN or EXISTSAn alternative for IN and EXISTS is an INNER JOIN, while a LEFT OUTER JOIN with a WHERE clause checking for NULL values can be used as an alternative for NOT IN and NOT EXISTS.


3 Answers

Given your updated question, these are the simplest forms:

If ProductID is unique you want

SELECT COUNT(*) FROM Products WHERE ProductID IN (1, 10, 100)

and then check that result against 3, the number of products you're querying (this last part can be done in SQL, but it may be easier to do it in C# unless you're doing even more in SQL).

If ProductID is not unique it is

SELECT COUNT(DISTINCT ProductID) FROM Products WHERE ProductID IN (1, 10, 100)

When the question was thought to require returning rows when all ProductIds are present and none otherwise:

SELECT ProductId FROM Products WHERE ProductID IN (1, 10, 100) AND ((SELECT COUNT(*) FROM Products WHERE ProductID IN (1, 10, 100))=3)

or

SELECT ProductId FROM Products WHERE ProductID IN (1, 10, 100) AND ((SELECT COUNT(DISTINCT ProductID) FROM Products WHERE ProductID IN (1, 10, 100))=3)

if you actually intend to do something with the results. Otherwise the simple SELECT 1 WHERE (SELECT ...)=3 will do as other answers have stated or implied.

like image 90
Mark Hurd Avatar answered Oct 02 '22 08:10

Mark Hurd


Here's how I usually do it:

Just replace your query with this statement SELECT * FROM table WHERE 1

SELECT
    CASE WHEN EXISTS 
    (
        SELECT * FROM table WHERE 1
    )
    THEN 'TRUE'
    ELSE 'FALSE'
END
like image 31
Mahmoud Zalt Avatar answered Oct 02 '22 08:10

Mahmoud Zalt


@Mark Hurd, thanks for pointing out the error.

this will work (if you are using Postgresql, Sql Server 2008):

create table products
(
product_id int not null
);



insert into products values(1),(2),(10),(100);

SELECT 
    CASE 
        WHEN EXISTS(
             SELECT 1 
             FROM (values(1),(10),(100)) as x(id) 
             WHERE x.id NOT IN (select product_id from products))
        THEN 0 --'NOT ALL'

        ELSE 1 -- 'ALL'
    END

If you are using MySQL, make a temporary memory table(then populate 1,10,100 there):

create table product_memory(product_id int) engine=MEMORY;

insert into product_memory values(1),(10),(100);

SELECT 
    CASE 
        WHEN EXISTS(
             SELECT 1 
             FROM product_memory
             WHERE product_memory.id NOT IN (select product_id from products))
        THEN 0 -- 'NOT ALL'

        ELSE 1 -- 'ALL'
    END

On your C# code:

bool isAllExist = (int)(new SqlCommand(queryHere).ExecuteScalar()) == 1;

[EDIT]

How can I write a query that will return a row if all the product id's exist and no row if one or more product id's does not exist?

Regarding, returning a row(singular) if all rows exists, and no row to be returned if one or more product id does not exists:

MySql:

SELECT 1
WHERE 
    NOT EXISTS(
        SELECT 1
             FROM product_memory
             WHERE product_memory.id NOT IN (select product_id from products) )

Posgresql, Sql Server 2008:

SELECT 1
WHERE 
    NOT EXISTS(            
        SELECT 1 
        FROM (values(1),(10),(100)) as x(id) 
        WHERE x.id NOT IN (select product_id from products) )

Then on your C# code:

var da = new SqlDataAdapter(queryhere, connectionhere);
var dt = new DataTable();
da.Fill(dt);

if (dt.Rows.Count > 0) 
    return true; 
else 
    return false;

Or just make the condition shorter:

return dt.Rows.Count > 0;
like image 13
Michael Buen Avatar answered Oct 02 '22 10:10

Michael Buen