What's the best/right/fastest/most appropriate way to detect if a row with a given rowid exists?
Or by extension, hwo to detect if at least one row matching a given condition exists?
I'm firing quite some of these requests. I am currently using
SELECT 1 FROM table WHERE condition LIMIT 1
looks a bit weird to me, but looks to me like "the least work" for the db, however, my SQL knowledge is spotty.
I would probably do it something like this:
SELECT
CASE
WHEN EXISTS(SELECT NULL FROM table1 WHERE ID=someid)
THEN 1
ELSE 0
END
To Count the rows is not that effective.
To check if something exists is in most cases more effective
Since it's sqlite, you need to use the column name "rowid" to access that id column. Using Craig Ringer's sql, the sqlite version would look like this:
SELECT EXISTS(SELECT 1 FROM table WHERE rowid = insert_number)
Use EXISTS, it sounds perfect for what you are after. e.g.
SELECT *
FROM T1
WHERE EXISTS (SELECT 1 FROM T2 WHERE T2.X = T1.X AND T2.Y = 1)
It is effectly the same as LIMIT 1 but is generally optimised better.
One could test
select true from table where id = id1
You can for example use
SELECT COUNT(*) FROM table WHERE ID = whatever
Related
I've got 2 tables with exactly the same structure in the same Sybase database but they're separate tables.
This query works on one of the 2:
select * from table1 where
QUOTA_FIELD >
(SELECT
count(ACCOUNT) FROM
table1 As t1
where SECTOR = t1.SECTOR
AND
STATUS = 'QUOTA'
)
But for the second table I have to change it to this:
select * from table2 as tref where
QUOTA_FIELD >
(SELECT
count(ACCOUNT) FROM
table2 As t2
where tref.SECTOR = t2.SECTOR
AND
STATUS = 'QUOTA'
)
There's a restriction on where this will execute which means it needs to work like in the first query.
Does anyone have any ideas as to why the first might work as expected and the second wouldn't?
Since I am not yet allowed to comment, here as an answer to the question "does anyone...?":
No. I couldn't find anyone :)
This first query cannot work correctly, since it compares a column with itself (as long as the column names are all normal ASCII characters and not some similar looking UNICODE ones). Please give a proof that the result of this query is in every case the same as of query 2.
Also, the second query would normally be done like that: where SECTOR = tref.SECTOR...
You might be looking for something like this in query #1 :
select * from table1 t2 where
QUOTA_FIELD >
(SELECT
count(ACCOUNT) FROM
table1 As t1
where t2.SECTOR = t1.SECTOR
AND
t1.STATUS = 'QUOTA'
)
This explicitly specifies that the table in subquery is joining with the table in outer query ( co-related subquery ).
If this works, use the same idea in query #2
Using Firebird:
I want to select a random entry in the table if the first SQL query returns 0 rows. Is there anyway to combine these two queries?
SELECT * FROM table WHERE cond=1;
SELECT FIRST 1 * FROM table ORDER BY rand();
Im using ExecuteNativeQuery on the java-side which takes basic SQL statements. Sadly, If-Else statements don't work. And if i could make a single query to the database instead of two, that would make my code appear faster.
try this: Not sure but think it will work...
Select FIRST 1 t1.*
FROM table t1
left Join Table t2
On t2.pk = t1.pk
And t2.cond=1
ORDER BY Case When t2.Cond = 1
Then 0 Else rand() End
if(exists(select 1 from table where cond=1))
SELECT * FROM table WHERE cond=1;
else
SELECT FIRST 1 * FROM table ORDER BY rand();
something like this, though I forgot whether the then keyword is needed in if statements in FirebirdSQL databases.
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.
How to Check whether a table contains rows or not sql server 2005?
For what purpose?
Quickest for an IF would be IF EXISTS (SELECT * FROM Table)...
For a result set, SELECT TOP 1 1 FROM Table returns either zero or one rows
For exactly one row with a count (0 or non-zero), SELECT COUNT(*) FROM Table
Also, you can use exists
select case when exists (select 1 from table)
then 'contains rows'
else 'doesnt contain rows'
end
or to check if there are child rows for a particular record :
select * from Table t1
where exists(
select 1 from ChildTable t2
where t1.id = t2.parentid)
or in a procedure
if exists(select 1 from table)
begin
-- do stuff
end
Like Other said you can use something like that:
IF NOT EXISTS (SELECT 1 FROM Table)
BEGIN
--Do Something
END
ELSE
BEGIN
--Do Another Thing
END
FOR the best performance, use specific column name instead of * - for example:
SELECT TOP 1 <columnName>
FROM <tableName>
This is optimal because, instead of returning the whole list of columns, it is returning just one. That can save some time.
Also, returning just first row if there are any values, makes it even faster. Actually you got just one value as the result - if there are any rows, or no value if there is no rows.
If you use the table in distributed manner, which is most probably the case, than transporting just one value from the server to the client is much faster.
You also should choose wisely among all the columns to get data from a column which can take as less resource as possible.
Can't you just count the rows using select count(*) from table (or an indexed column instead of * if speed is important)?
If not then maybe this article can point you in the right direction.
Fast:
SELECT TOP (1) CASE
WHEN **NOT_NULL_COLUMN** IS NULL
THEN 'empty table'
ELSE 'not empty table'
END AS info
FROM **TABLE_NAME**
I am trying to find a way, if possible, to use IN and LIKE together. What I want to accomplish is putting a subquery that pulls up a list of data into an IN statement. The problem is the list of data contains wildcards. Is there any way to do this?
Just something I was curious on.
Example of data in the 2 tables
Parent table
ID Office_Code Employee_Name
1 GG234 Tom
2 GG654 Bill
3 PQ123 Chris
Second table
ID Code_Wildcard
1 GG%
2 PQ%
Clarifying note (via third-party)
Since I'm seeing several responses which don't seems to address what Ziltoid asks, I thought I try clarifying what I think he means.
In SQL, "WHERE col IN (1,2,3)" is roughly the equivalent of "WHERE col = 1 OR col = 2 OR col = 3".
He's looking for something which I'll pseudo-code as
WHERE col IN_LIKE ('A%', 'TH%E', '%C')
which would be roughly the equivalent of
WHERE col LIKE 'A%' OR col LIKE 'TH%E' OR col LIKE '%C'
The Regex answers seem to come closest; the rest seem way off the mark.
I'm not sure which database you're using, but with Oracle you could accomplish something equivalent by aliasing your subquery in the FROM clause rather than using it in an IN clause. Using your example:
select p.*
from
(select code_wildcard
from second
where id = 1) s
join parent p
on p.office_code like s.code_wildcard
In MySQL, use REGEXP:
WHERE field1 REGEXP('(value1)|(value2)|(value3)')
Same in Oracle:
WHERE REGEXP_LIKE(field1, '(value1)|(value2)|(value3)')
Do you mean somethign like:
select * FROM table where column IN (
SELECT column from table where column like '%%'
)
Really this should be written like:
SELECT * FROM table where column like '%%'
Using a sub select query is really beneficial when you have to pull records based on a set of logic that you won't want in the main query.
something like:
SELECT * FROM TableA WHERE TableA_IdColumn IN
(
SELECT TableA_IdColumn FROM TableB WHERE TableA_IDColumn like '%%'
)
update to question:
You can't combine an IN statement with a like statement:
You'll have to do three different like statements to search on the various wildcards.
You could use a LIKE statement to obtain a list of IDs and then use that in the IN statement.
But you can't directly combine IN and LIKE.
Perhaps something like this?
SELECT DISTINCT
my_column
FROM
My_Table T
INNER JOIN My_List_Of_Value V ON
T.my_column LIKE '%' + V.search_value + '%'
In this example I've used a table with the values for simplicity, but you could easily change that to a subquery. If you have a large list (like tens of thousands) then performance might be rough.
select *
from parent
where exists( select *
from second
where office_code like trim( code_wildcard ) );
Trim code_wildcard just in case it has trailing blanks.
You could do the Like part in a subquery perhaps?
Select * From TableA Where X in (Select A from TableB where B Like '%123%')
tsql has the contains statement for a full-text-search enabled table.
CONTAINS(Description, '"sea*" OR "bread*"')
If I'm reading the question correctly, we want all Parent rows that have an Office_code that matches any Code_Wildcard in the "Second" table.
In Oracle, at least, this query achieves that:
SELECT *
FROM parent, second
WHERE office_code LIKE code_wildcard;
Am I missing something?