Выберите только те строки, которые находятся в нескольких результирующих наборах - PullRequest
0 голосов
/ 10 февраля 2020

У меня есть несколько операторов SELECT, которые возвращают одни и те же столбцы, но могут возвращать разные наборы результатов. Есть ли способ выбрать все строки, которые есть в всех наборах результатов на уровне базы данных?

Например:

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

РЕДАКТИРОВАТЬ: Это очень упрощенный пример моей проблемы , Операторы могут быть очень сложными (объединяются по нескольким таблицам), поэтому простой AND в части WHERE не является окончательным решением.

Результат должен быть Pascal. То, что я ищу, это что-то вроде «обратного UNION».

В качестве альтернативы можно было бы достичь этого программно (NodeJS), но я бы хотел избежать перебора всех наборов результатов, потому что они могут быть довольно огромными.

Заранее спасибо!

Ответы [ 4 ]

2 голосов
/ 10 февраля 2020

Есть ли способ выбрать все строки во всех наборах результатов?

Вы, кажется, хотите and:

select name 
from table 
where age > 40 and name like 'P%' and id < 3
1 голос
/ 10 февраля 2020

Если использование AND между условиями WHERE невозможно, вы можете использовать несколько выражений IN для подзапросов, используя ваши первоначальные запросы.

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)
0 голосов
/ 10 февраля 2020

Если ваши операторы сложны, вы можете использовать процедуру, в которой каждое из операторов помещает соответствующие идентификаторы во временную таблицу. Затем выберите те строки, где идентификаторы соответствуют числу операторов. Это также, скорее всего, будет более эффективным, чем один огромный запрос, в котором все сложные операторы объединены в один.

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
0 голосов
/ 10 февраля 2020

Если у вас разные наборы результатов, и вы хотите увидеть пересечение, вы можете использовать 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;

Тем не менее, я думаю, что у GMB есть самый краткий ответ на вопрос, который вы на самом деле спросил.

...