Way to try multiple SELECTs till a result is available?
LIKE
without wildcard character is equivalent to =
. Assuming you actually meant name = 'text'
.
Indexes are the key to performance.
Test setup
CREATE TABLE image (
image_id serial PRIMARY KEY
, group_id int NOT NULL
, name text NOT NULL
);
Ideally, you create two indexes (in addition to the primary key):
CREATE INDEX image_name_grp_idx ON image (name, group_id);
CREATE INDEX image_grp_idx ON image (group_id);
The second may not be necessary, depending on data distribution and other details. Explanation here:
- Is a composite index also good for queries on the first field?
Query
This should be the fastest possible query for your case:
SELECT * FROM image WHERE name = 'name105' AND group_id = 10
UNION ALL
SELECT * FROM image WHERE name = 'name105'
UNION ALL
SELECT * FROM image WHERE group_id = 10
LIMIT 1;
SQL Fiddle.
The LIMIT
clause applies to the whole query. Postgres is smart enough not to execute later legs of the UNION ALL
as soon as it has found enough rows to satisfy the LIMIT
. Consequently, for a match in the first SELECT
of the query, the output of EXPLAIN ANALYZE
looks like this (scroll to the right!):
Limit (cost=0.00..0.86 rows=1 width=40) (actual time=0.045..0.046 rows=1 loops=1)
Buffers: local hit=4
-> Result (cost=0.00..866.59 rows=1002 width=40) (actual time=0.042..0.042 rows=1 loops=1)
Buffers: local hit=4
-> Append (cost=0.00..866.59 rows=1002 width=40) (actual time=0.039..0.039 rows=1 loops=1)
Buffers: local hit=4
-> Index Scan using image_name_grp_idx on image (cost=0.00..3.76 rows=2 width=40) (actual time=0.035..0.035 rows=1 loops=1)
Index Cond: ((name = 'name105'::text) AND (group_id = 10))
Buffers: local hit=4
-> Index Scan using image_name_grp_idx on image (cost=0.00..406.36 rows=500 width=40) (never executed)
Index Cond: (name = 'name105'::text)
-> Index Scan using image_grp_idx on image (cost=0.00..406.36 rows=500 width=40) (never executed)
Index Cond: (group_id = 10)
Total runtime: 0.087 ms
Bold emphasis mine.
Do not add an ORDER BY
clause, this would void the effect. Then Postgres would have to consider all rows before returning the top row.
Final questions
Is there a generic solution for that?
This is the generic solution. Add as many SELECT
statements as you want.
Of course it would come in handy when the search result is sorted by its relevance.
There is only one row in the result with LIMIT 1
. Kind of voids sorting.
How does one populate a structure using multiple select statements
Your statement will return multiple result sets, If you are using DataReader, then you will get multiple results. Use DataReader.NextResult
method to get next result set and show data accordingly.
If you are not concerned about DataReader
then you can use DataSet
and use a DataAdapater
to fill out the results in multiple DataTables
inside the DataSet.
MySQL Multiple SELECT queries with different WHERE clause on the same table
Use select union and not in
SELECT * from tbl_fruits WHERE fruit = "Apple" AND vit = "A" AND city = "London"
union
SELECT * from tbl_fruits WHERE fruit = "Apple" AND vit = "B" AND city != "London
union
SELECT * from tbl_fruits WHERE fruit = "Apple" AND vit NOT IN ( "A" , "B" ) AND city != "London";
How do I Put Several Select Statements into Different Columns
You could use a series of queries unioned together. Kind of ugly, but it should work
SELECT
COUNT(user_id) AS '20100101'
,NULL AS '20100102'
,NULL AS '20100103'
,NULL AS '20100104'
,NULL AS '20100105'
FROM
event_log_facts
WHERE
date_dim_id=20100101
UNION
SELECT
NULL AS '20100101'
,COUNT(user_id) AS '20100102'
,NULL AS '20100103'
,NULL AS '20100104'
,NULL AS '20100105'
FROM
event_log_facts
WHERE
date_dim_id=20100102
UNION
SELECT
NULL AS '20100101'
,NULL AS '20100102'
,COUNT(user_id) AS '20100103'
,NULL AS '20100104'
,NULL AS '20100105'
FROM
event_log_facts
WHERE
date_dim_id=20100103
ETC...
How to execute a 2nd query if the first one returns nothing?
For multiple rows
WITH fast AS (
SELECT column1, column2
FROM mytable
WHERE <1st SET OF complex conditions>
)
, slow AS (
SELECT column1, column2
FROM mytable
WHERE NOT EXISTS (TABLE fast)
AND <2nd SET OF complex conditions>
)
TABLE fast
UNION ALL
TABLE slow;
Test with EXPLAIN ANALYZE
: you'll see (never executed)
for the second query (CTE slow
) if the first one (CTE fast
) returns any rows. I think that's what you are aiming for.
TABLE fast
is just (standard SQL) short syntax for SELECT * FROM fast
. See:
- Is there a shortcut for SELECT * FROM?
Simpler for a single returned row
If both queries can only return a single row (or nothing), there is a simple, efficient solution without CTEs:
(
SELECT column1, column2
FROM mytable
WHERE <1st SET OF complex conditions>
)
UNION ALL
(
SELECT column1, column2
FROM mytable
WHERE <2nd SET OF complex conditions>
)
LIMIT 1;
Related:
- Select first record if none match
- Way to try multiple SELECTs till a result is available?
Is it possible to do multiple SQL select statements within one query? Both select statements would be on the same table
You should use a UNION statement.
SELECT hostname FROM mytable
WHERE hostname
NOT LIKE '%obl%' AND
group NOT IN ('group1','group2','group3','group4','group5','group6','group7')
AND osname LIKE '%Windows%'
AND hostname not LIKE 'nic%'
UNION
SELECT hostname FROM mytable
WHERE hostname
LIKE '%obl%'
AND group in ('group9','group0')
That will do it, but I think you could rethink those where conditions. I'll give it a thought and edit if necessary.
EDIT: You can achieve what you are trying to with a single query, no need for the union.
SELECT hostname FROM mytable
WHERE (
hostname NOT LIKE '%obl%'
AND group NOT IN ('group1','group2','group3','group4','group5','group6','group7')
AND osname LIKE '%Windows%'
AND hostname NOT LIKE 'nic%'
)
OR (
hostname LIKE '%obl%'
AND group IN ('group9','group0')
)
How to get all selected values of a multiple select box?
No jQuery:
// Return an array of the selected opion values
// select is an HTML select element
function getSelectValues(select) {
var result = [];
var options = select && select.options;
var opt;
for (var i=0, iLen=options.length; i<iLen; i++) {
opt = options[i];
if (opt.selected) {
result.push(opt.value || opt.text);
}
}
return result;
}
Quick example:
<select multiple>
<option>opt 1 text
<option value="opt 2 value">opt 2 text
</select>
<button onclick="
var el = document.getElementsByTagName('select')[0];
alert(getSelectValues(el));
">Show selected values</button>
Retrieve data from stored procedure which has multiple result sets
It seems like there's no good simple way to do this, without a hack or a major paradigm shift. It looks like the best way is to just split out the original procs and end up with one more proc than before:
Old way:
create procedure dbo.GetSomething
as
begin
select * from dbo.Person;
select * from dbo.Car;
end;
New way:
create procedure dbo.GetPeople
as
begin
select * from dbo.Person;
end;
create procedure dbo.GetCars
as
begin
select * from dbo.Car;
end;
-- This gives the same result as before
create procedure dbo.GetSomething
as
begin
exec dbo.GetPeople;
exec dbo.GetCars;
end;
Then when I'm in a different proc and need both result sets, I'd just have to call them one at a time.
is there a pythonic way to try something up to a maximum number of times?
How about:
conn = MySQLdb.connect(host, user, password, database)
cursor = conn.cursor()
attempts = 0
while attempts < 3:
try:
cursor.execute(query)
rows = cursor.fetchall()
for row in rows:
# do something with the data
break
except MySQLdb.Error, e:
attempts += 1
print "MySQL Error %d: %s" % (e.args[0], e.args[1])
Related Topics
How to Search Multiple Columns in MySQL
How to Set Auto Increment Primary Key in Postgresql
Hierarchical Data in Linq - Options and Performance
How to Create a Copy of an Oracle Table Without Copying the Data
How to Convert a SQL Server 2008 Datetimeoffset to a Datetime
Merge Overlapping Date Intervals
Dynamic Update Statement with Variable Column Names
SQL Selecting Rows by Most Recent Date with Two Unique Columns
How to Include Null Values in a Min or Max
Best Way to Count Rows by Arbitrary Time Intervals
List Columns with Indexes in Postgresql
SQL Error: Ora-01861: Literal Does Not Match Format String 01861
Mysql: Transactions VS Locking Tables
What Does Delimiter // Do in a Trigger
How to See Active SQL Server Connections
Perform This Hours of Operation Query in Postgresql
How to Remove Redundant Namespace in Nested Query When Using for Xml Path