简体   繁体   中英

Is there a way to select values from a column based on the comparison of another column with a subquery returning multiple rows?

I'll try to clarify the question in the title with an example,

You have a table X , this table contains the columns foo VARCHAR and bar INT The values in the table are as following:

   TABLE X
-------------
| foo | bar |
-------------
| 'a' |  1  |
| 'a' |  2  |
| 'a' |  3  |
| 'b' |  1  |
| 'b' |  2  |
| 'c' |  1  |
-------------

And in order to simplify, we're going to take an example of what the subquery could return, let's say (1,2)

What I would like to obtain using (1,2) is this:

----------
| result |
----------
|  'a'   |
|  'b'   |
----------

Because a and b are the only ones with 1 and 2 in the bar column.

So basically, what I want to do is get all the foo values that have all the bar values returned by the subquery.

However, I don't know if this is possible because I need to group multiple columns with the same foo and then compare their bar to the values returned by the subquery.

If you want to try yourself here is a Minimal Reproductive Example, you can go on https://sqliteonline.com/

Make sure to use MySQL or MariaDB

CREATE TABLE X (
    foo VARCHAR(16) NOT NULL,
    bar INT NOT NULL,
    PRIMARY KEY (foo,bar)
);

INSERT INTO X(foo,bar) VALUES ('a', 1);
INSERT INTO X(foo,bar) VALUES ('a', 2);
INSERT INTO X(foo,bar) VALUES ('a', 3);
INSERT INTO X(foo,bar) VALUES ('b', 1);
INSERT INTO X(foo,bar) VALUES ('b', 2);
INSERT INTO X(foo,bar) VALUES ('c', 1);

You don't need to use a subquery, you can just assume that it's going to returned either (1) , (1,2) , (2,3) , (1,2,3) or every other combination (the order doesn't matter).

You can use aggregation and filtering:

select foo
from x
where bar in (1, 2)
group by foo
having count(*) = 2;  -- number of items in the list of bars

You example data doesn't have duplicates. But if it did, use count(distinct bar) = 2 instead.

EDIT:

If you have a subquery, then use:

with s as (
      <subquery here>
     )
select foo
from x join
     s
     on s.bar = x.bar
group by foo
having count(*) = (select count(*) from s);

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