Talha Ahmed Khan
Talha Ahmed Khan

Reputation: 15453

Same sub-query used multiple times in a single query

I am running a query that contains same sub-query used multiple times in a WHERE clause.

I have a table having tow fields client_id, buyer_id.

The sub-query returns the list of dates to be excluded from the result.

This is how I am using it.

SELECT
  id, client_id, buyer_id
FROM relation
WHERE
  client_id NOT IN (SELECT <some_id> FROM <some_table> WHERE ...)
  AND buyer_id NOT IN (SELECT <some_ids> FROM <some_table> WHERE ...)

This is working as expected but what bothers me that there are two same sub-queries. I wonder if there is a way that I can use it once and use the result for both places.

Thanks.

Upvotes: 8

Views: 5807

Answers (4)

user359040
user359040

Reputation:

Queries of the form:

select ...
from <main query>
where <select field> not in (select <subquery field> from <subquery>)

can normally be reformulated as:

select <main query fields>
from <main query>
left join <subquery> on <select field> = <subquery field>
where <subquery field> is null

If the sub-query you are using is exactly the same for both client_id and buyer_id, it should therefore be possible to reformulate your query as:

SELECT id, client_id, buyer_id
FROM relation
LEFT JOIN <some_table> ON <some_id> IN (client_id, buyer_id)
WHERE <some_id> IS NULL

- thus effectively using the subquery only once in the query.

Upvotes: 1

ypercubeᵀᴹ
ypercubeᵀᴹ

Reputation: 115600

You can write this using NOT EXISTS:

SELECT
    id, client_id, buyer_id
FROM relation AS r
WHERE NOT EXISTS
      ( SELECT 1 
        FROM <some_table> 
        WHERE (r.client_id = <some_id> OR r.buyer_id = <some_id>) 
          AND ...
      ) ;

Upvotes: 3

efraimo
efraimo

Reputation: 1

It would be of help to try putting the fetched values into a separate database table, so that whether there are similar result values or different can now be decided when you already have your results in a separate table. Waiting to hear from your proceedings... Good luck pls.

Upvotes: 0

RandomSeed
RandomSeed

Reputation: 29769

Your query could be transformed as follows:

SELECT
  id, client_id, buyer_id
FROM relation
LEFT JOIN some_table
) AS subquery ON ( subquery.some_id IN (client_id, buyer_id) AND <condition that was in your subquery>)
WHERE subquery.some_id IS NULL;

But I have the feeling this will still perform very poorly in terms of execution time.

Consider building a temporary table holding the contents of your subquery.

Upvotes: 0

Related Questions