tags:

views:

164

answers:

3

In Jet, I want to test if certain conditions return any results.

I want a query which returns exactly one record: "true" if there are any results, "false" otherwise.

This works in MS SQL:

SELECT
  CASE
    WHEN EXISTS(SELECT * FROM foo WHERE <some condition>)
    THEN 1
    ELSE 0
  END;

This is what I have tried in Jet:

SELECT IIF(EXISTS(SELECT * FROM foo WHERE <some condition>), 0, 1);

which gives me the error:

Reserved error (-3025); there is no message for this error.

Any ideas?

NOTE I don't want to select "true" multiple times by tacking on a FROM clause at the end, because it could be slow (if the FROM table had many records) or undefined (if the table had 0 records).

A: 

Most EXISTS queries can be re-written as a left join:

    SELECT
      CASE
        WHEN foo.col is NULL 
        THEN 0
        ELSE 1
    END;
   ... LEFT JOIN foo on <where condition>
Bill
I want to get one and only one result no matter what records are there... or aren't. This is why left joins won't work for me. I could use count, but I don't want it to have to look at each record it pulls up before deciding there are more than 0 records.
des4maisons
+1  A: 

How about:

SELECT TOP 1 IIF(EXISTS(
       SELECT * FROM foo 
       WHERE <some condition>), 0, 1) As f1 
FROM foo

Perhaps more clearly:

SELECT TOP 1 IIF(EXISTS(
       SELECT * FROM foo
       WHERE <some condition>), 0, 1) As F1 
FROM MSysObjects
Remou
By adding the from clause, I end up selecting the result of the test, but I get as many records as there are in foo. I would only like to get one record.
des4maisons
SELECT TOP 1 ok for you?
Remou
@Remou not with an iif immediately following, and who knows what would happen if the FROM table for some reason had no records.
des4maisons
You can use any table or query that has records to select the top 1 from, above is an example using a system table from Access.
Remou
I don't see any problem at all with the TOP 1 IIf(). I've just tested Remou's SQL in Access and it works just fine. You haven't identified where you're running this SQL -- perhaps it's from outside Access and that's the problem? If so, you might move the TOP 1 from the SELECT to the FROM by using "FROM (SELECT TOP 1 MSysObjects)".
David-W-Fenton
+ 1: using TOP 1 is much faster than DISTINCT... though DISTINCT only takes about 300 ms on my machine using a 100K row table ;)
onedaywhen
Yah, you're right, TOP 1 works, though it still requires a FROM clause. I guess that will have to be my compromise. Thanks all!
des4maisons
+1  A: 

You might be able to use a count

SELECT DISTINCT IIF((SELECT COUNT(*) AS Result FROM [Data Set]), 1, 0) FROM [Data Set];
Thanks! That's almost what I want to do, except (though I don't know the inner workings of Jet that well) I suspect that DISTINCT needs to look at each record. I just want to get the result of the EXISTS clause, which would be nice and fast, always.
des4maisons
(and for that matter, COUNT needs to look at each record.)
des4maisons
@des4maisons - Just a thought, but could you create a Dummy Table with 1 record in it and in the *last* FROM clause instead of [Data Set] you would put [Dummy Table]? That would probably eliminate the DISTINCT.
@des4maisons - Use EXISTS or use COUNT, what ever suits your needs. I didn't know that Jet SQL supported EXISTS.
@roygbiv yah that would work ... unfortunately this software is to be run on our clients' databases, and we don't want to add to their databases without a really good reason.
des4maisons
@des4maisons - Does Jet SQL support the TOP clause? SELECT TOP 1...
@roygbiv not with an iif statement right afterwards. Also, if the FROM table happened to have no results, who knows what the behaviour would be.
des4maisons