Determine existence of results in jet SQL? - sql

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

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

You might be able to use a count
SELECT DISTINCT IIF((SELECT COUNT(*) AS Result FROM [Data Set]), 1, 0) FROM [Data Set];

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>

Related

Check if all rows are the same

I have a select query that returns multiple rows, and I want to check if all rows are the same. So something like this:
anything_other_than(123) in (select id from foo)
So, if select id from foo returns 111,222,123,333 the statement above is false, and if select id from foo returns 123,123,123 it's true. How can I achieve this?
A simple solution is to use the = ALL operator:
SELECT 123 = ALL (SELECT id FROM foo);
This solution also stop scanning the result as soon as the first non-matching value is found.
Another option is to use EXISTS with a where condition:
select not exists (select *
from the_table
where id <> 123);
Run this:
select count(distinct id) = 1 and count(*) > 1 from foo;
count(distinct id) will return 1 if all the rows are the same
and count(*) will return the total number of rows.
If this returns true then you have more than 1 rows and all the rows are the same.
You can use something like this -
select x, IF(x > 1, "FALSE", "TRUE") from
(SELECT count(distinct(A.id)) as x FROM foo as A) as B;
Do refer this https://www.w3schools.com/sql/func_mysql_if.asp

SQL - If Select returns nothing then do another Select

I'm currently trying to do an SQL query that can detect if a SELECT query returns nothing, and then do another one if that is the case.
Here is what I mean:
IF SELECT * FROM table WHERE criteria = criteria RETURNS NO ROWS
THEN SELECT * FROM table WHERE criteria2 = criteria2
Is this possible? I don't think that an empty reply counts as "null" so I have a bit of a trouble with that.
You can do this in one statement, assuming the columns are the same:
SELECT *
FROM table
WHERE criteria = criteria
UNION ALL
SELECT *
FROM table
WHERE criteria2 = criteria2 AND
NOT EXISTS (SELECT 1 FROM table WHERE criteria = criteria);
You can use NOT EXISTS:
SELECT * FROM table WHERE criteria2 = criteria2
and not exists (
SELECT * FROM table WHERE criteria = criteria
)
union all
SELECT * FROM table WHERE criteria = criteria;
Here NOT EXISTS ensures that either part of the UNION ALL is returned. If the second criteria = criteria passes, then NOT EXISTS will return false and hence, only second part of the above query returns result. If it doesn't, it means, there are no rows with criteria = criteria and NOT EXISTS will return true and hence, only the first part return data.
I Did it like this
WITH
First AS (
SELECT t1.<field1>
FROM <schema1>.<table1> t1
WHERE
<criteria1>
[Other SQL Queries Options]
OFFSET 0
LIMIT 1
),
Second AS (
SELECT t2.<field2>
FROM <schema2>.<table2> t2
WHERE
<criteria2>
[Other SQL Queries Options]
OFFSET 0
LIMIT 1
)
SELECT <field1>
FROM First
UNION ALL
SELECT <field2> as <same name as field1>
FROM Second
WHERE NOT exists(
SELECT 1 FROM First
)
;

SQL Server check if where clause is true for any row

I'm going to select those provinces which intersects any railroad. So I do it like this (Using SQL Spatial):
SELECT * FROM ProvinceTable
WHERE (
SELECT count(*)
FROM RailroadTable
WHERE ProvinceTable.Shape.STIntersects(RailroadTable.Shape) > 1
) > 0
But it is not efficient because it has to check the intersection between every single railroad geometry and province geometry in order to calculate the count. However it is better to stop the where clause as soon as every first intersection detected and there is no need to check others. Here is what I mean:
SELECT * FROM ProvinceTable
WHERE (
--return true if this is true for any row in the RailroadTable:
-- "ProvinceTable.Shape.STIntersects(RailroadTable.Shape) > 1"
)
So is there a better way to rewrite this query for such a goal?
EDIT
Surprisingly This query takes the same time and returns no row:
SELECT * FROM ProvinceTable
WHERE EXISTS (
SELECT *
FROM RailroadTable
WHERE ProvinceTable.Shape.STIntersects(RailroadTable.Shape) > 1
)
You want to use exists:
SELECT pt.*
FROM ProvinceTable pt
WHERE EXISTS (SELECT 1
FROM RailroadTable rt
WHERE pt.Shape.STIntersects(rt.Shape) = 1
);

Yield Return equivalent in SQL Server

I am writing down a view in SQL server (DWH) and the use case pseudo code is:
-- Do some calculation and generate #Temp1
-- ... contains other selects
-- Select statement 1
SELECT * FROM Foo
JOIN #Temp1 tmp on tmp.ID = Foo.ID
WHERE Foo.Deleted = 1
-- Do some calculation and generate #Temp2
-- ... contains other selects
-- Select statement 2
SELECT * FROM Foo
JOIN #Temp2 tmp on tmp.ID = Foo.ID
WHERE Foo.Deleted = 1
The result of the view should be:
Select Statement 1
UNION
Select Statement 2
The intended behavior is the same as the yield returnin C#. Is there a way to tell the view which SELECT statements are actually part of the result and which are not? since the small calculations preceding what I need also contain selects.
Thank you!
Yield return in C# returns rows one at a time as they appear in some underlying function. This concept does not exist in SQL statements. SQl is set-based, returning the entire result set, conceptually as a unit. (That said, sometimes queries run slowly and you will see rows returned slowly or in batches.)
You can control the number of rows being returns using TOP (in SQL Server). You can select particular rows to be returned using WHERE statements. However, you cannot specify a UNION statement that conditionally returns rows from some components but not others.
The closest you may be able to come is something like:
if UseTable1Only = 'Y'
select *
from Table1
else if UseTable2Only = 'Y'
select *
from Table2
else
select *
from table1
union
select *
from table2
You can do something similar using dynamic SQL, by constructing the statement as a string and then executing it.
I found a better work around. It might be helpful for someone else. It is actually to include all the calculation inside WITH statements instead of doing them in the view core:
WITH Temp1 (ID)
AS
(
-- Do some calculation and generate #Temp1
-- ... contains other selects
)
, Temp2 (ID)
AS
(
-- Do some calculation and generate #Temp2
-- ... contains other selects
)
-- Select statement 1
SELECT * FROM Foo
JOIN Temp1 tmp on tmp.ID = Foo.ID
WHERE Foo.Deleted = 1
UNION
-- Select statement 2
SELECT * FROM Foo
JOIN Temp2 tmp on tmp.ID = Foo.ID
WHERE Foo.Deleted = 1
The result will be of course the UNION of all the outiside SELECT statements.

return a default record from a sql query

I have a sql query that I run against a sql server database eg.
SELECT * FROM MyTable WHERE Id = 2
This may return a number of records or may return none. If it returns none, I would like to alter my sql query to return a default record, is this possible and if so, how? If records are returned, the default record should not be returned. I cannot update the data so will need to alter the sql query for this.
Another way (you would get an empty initial rowset returned);
SELECT * FROM MyTable WHERE Id = 2
IF (##ROWCOUNT = 0)
SELECT ...
SELECT TOP 1 * FROM (
SELECT ID,1 as Flag FROM MyTable WHERE Id = 2
UNION ALL
SELECT 1,2
) qry
ORDER BY qry.Flag ASC
You can have a look to this post. It is similar to what you are asking
Return a value if no rows are found SQL
I hope that it can guide you to the correct path.
if not exists (SELECT top 1 * FROM mytable WHERE id = 2)
select * from mytable where id= 'whatever_the_default_id_is'
else
select * from mytable where id = 2
If you have to return whole rows of data (and not just a single column) and you have to create a single SQL query then do this:
Left join actual table to defaults single-row table
select
coalesce(a.col1, d.col1) as col1,
coalesce(a.col2, d.col2) as col2,
...
from (
-- your defaults record
select
default1 as col1,
default2 as col2,
...) as d
left join actual as a
on ((1 = 1) /* or any actual table "where" conditions */)
The query need to return the same number of fields, so you shouldn't do a SELECT * FROM but a SELECT value FROM if you want to return a default value.
With that in mind
SELECT value FROM MyTable WHERE Id = 2
UNION
SELECT CASE (SELECT count(*) FROM MyTable WHERE Id = 2)
WHEN 0 THEN 'defaultvalue'
END