简体   繁体   中英

Select only those rows that are in multiple result sets

I have multiple SELECT statements that all return the same columns but may return different resultsets. Is there any way to select all rows that are in all resultsets on database level?

Eg

|---------------------|------------------|---------|
|          ID         |        Name      |   Age   |
|---------------------|------------------|---------|
|          1          |       Paul       |   50    |
|          2          |       Peter      |   40    |
|          3          |       Frank      |   20    |
|          4          |       Pascal     |   60    |
|---------------------|------------------|---------|

SELECT 1
SELECT name FROM table WHERE age > 40
Result: Paul, Pascal

SELECT 2
SELECT name FROM table where name like 'P%'
Result: Paul, Peter, Pascal

SELECT 3 
SELECT name FROM table where id > 3
Result: Pascal

EDIT: This is a very simplified example of my problem. The statements can get very complex (joins over multiple tables), so a simple AND in the WHERE part is not the final solution.

The result should be Pascal . What I am looking for is something like a "reverse UNION ".

Alternatively it would be possible to achieve that programatically (NodeJS), but I would like to avoid to iterate over all resultsets, because they might be quite huge.

Thanks in advance!

Is there any way to select all rows that are in all resultsets?

You seem to want and :

select name 
from table 
where age > 40 and name like 'P%' and id < 3

If using AND between the WHERE conditions is not possible, you could use multiple IN expressions on subqueries using your initial queries.

SELECT name
FROM table
WHERE id IN (SELECT id FROM table WHERE age > 40)
  AND id IN (SELECT id FROM table where name like 'P%')
  AND id IN (SELECT id FROM table where id < 3)

If you have different result sets and you want to see the intersection, you can use join :

select q1.id
from (<query 1>) q1 join
     (<query 2>) q2
     on q1.id = q2.id join
     (<query 3>) q3
     on q1.id = q3.id;

That said, I think GMB has the most concise answer to the question that you actually asked.

If your statements are complex, what you could do is to use a procedure where each of the statements put the matching id's into a temp table. Then select those rows where id's match the number of statements. This will also most likely be more efficient than one huge query with all complex statements combined into one.

create procedure sp_match_all()
begin

drop temporary table if exists match_tmp;
create temporary table match_tmp (
id int
);

insert into match_tmp
SELECT id FROM table WHERE age > 40;

insert into match_tmp
SELECT id FROM table where name like 'P%';

insert into match_tmp
SELECT id FROM table where id < 3;

select t.name
from table t
  join (
    select id
    from match_tmp
    group by id
    having count(*)=3
  ) q on q.id=t.id;

drop temporary table match_tmp;

end

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM