I want to return results matching a key
where all parts
are present. Given:
create table things (
id int not null,
key int not null,
part character varying(1),
details character varying(64),
CONSTRAINT things_pkey PRIMARY KEY (id)
);
And this:
id | key | part | details |
---|---|---|---|
1 | 1 | a | 1a details |
2 | 1 | b | 1b details |
3 | 1 | c | 1c details |
4 | 2 | a | 2a details |
5 | 2 | b | 2b details |
6 | 2 | c | 2c details |
7 | 3 | a | 3a details |
8 | 3 | c | 3c details |
9 | 4 | b | 4b details |
10 | 5 | b | 5b details |
11 | 6 | b | 6b details |
12 | 6 | c | 6c details |
13 | 7 | a | 7a details |
14 | 8 | a | 8a details |
I can get to this:
id | key | part | details |
---|---|---|---|
1 | 1 | a | 1a details |
2 | 1 | b | 1b details |
3 | 1 | c | 1c details |
4 | 2 | a | 2a details |
5 | 2 | b | 2b details |
6 | 2 | c | 2c details |
With this query:
select *
from things t
where t.key in (
select x.key
from things x
group by x.key
having count(distinct part) = 3
);
But I really want to match the distinct part, not just the count of it, e.g. having distinct part = ['a', 'b', 'c']
. Can I do this in the query or just do it in the application code?
http://sqlfiddle.com/#!17/38b399/6
Edit
Essentially, what I'm after is a chunk of rows where all the part
s for a thing
are present. There are eight parts to a thing. They'll be processed and the records in this table deleted. Repeat forever.
Here is the CREATE
script from pgAdmin (with reduced noise):
CREATE TABLE public.things (
id uuid PRIMARY KEY,
key character varying(255) COLLATE pg_catalog."default" NOT NULL,
part character varying(3) COLLATE pg_catalog."default" NOT NULL,
details character varying(1024) COLLATE pg_catalog."default",
timezone character varying(128) COLLATE pg_catalog."default",
client_id uuid,
CONSTRAINT things_client_id_fkey FOREIGN KEY (client_id)
REFERENCES public.clients (id)
);
CREATE INDEX things_client_id_index ON public.things (client_id);
CREATE UNIQUE INDEX unique_things ON public.things (key, part, client_id);