检索具有不同条件的可变数量的子集

时间:2018-12-27 19:51:34

标签: sql database postgresql

我有以下数据库:

CREATE TABLE IF NOT EXISTS city (
    id  serial primary key,
    name    character varying UNIQUE NOT NULL
);

CREATE TABLE IF NOT EXISTS inhabitants (
    id  serial primary key,
    fullname    character varying UNIQUE NOT NULL,
    home    integer REFERENCES city
);

INSERT INTO city (name) VALUES
('michigan'),
('washington'),
('new york'),
('london'),
('los angeles')
ON CONFLICT DO NOTHING;

INSERT INTO inhabitants (fullname, home) VALUES
('flannigan, amy', 1),
('hannigan, leon', 1),
('shennanigan, frank', 1),
('catcher, floyd', 2),
('rice, amy', 2),
('black, joe', 2),
('higgins, simon', 3),
('stewart, rick', 3),
('white, frank', 3),
('henson, ben', 5),
('hedge, tim', 5),
('wilson, bill', 5),
('moriarty, doc', 4),
('fletcher, dolores', 4),
('fletcher, hank', 4),
('williamson, ann', 1),
('stewart, mary', 3)
ON CONFLICT DO NOTHING;

我想为每个子集提取不同数量的子集,其中包含不同数量的居民。目前,我对每个子集使用查询,例如,如果我需要两个子集,则可以使用以下两个查询:

select fullname, home from inhabitants i
where home = (SELECT id FROM city WHERE name = 'michigan')
ORDER BY random() LIMIT 2;

select fullname, home from inhabitants i
where home = (SELECT id FROM city WHERE name = 'london')
ORDER BY random() LIMIT 1;

结果可能看起来像这样:

    fullname     | home 
-----------------+------
 hannigan, leon  |    1
 williamson, ann |    1
(2 rows)

     fullname      | home 
-------------------+------
 fletcher, dolores |    4
(1 row)

我在Bash中加入了这两个结果,所以它们看起来确实是我想要的:

    fullname       | home 
-------------------+------
 hannigan, leon    |    1
 williamson, ann   |    1
 fletcher, dolores |    4
(3 rows)

我想减少数据库调用的次数。

有没有一种方法可以执行一个查询(或函数),或者至少比我目前正在做的更好的方法?

1 个答案:

答案 0 :(得分:0)

使用窗口功能:

select fullname, home 
from (select i.*, 
             row_number() over (partition by home order by random()) as seqnum
      from inhabitants i
     ) i join
     city c
     on c.id = i.home
where (name = 'michigan' and seqnum <= 2) or
      (name = 'london' and seqnum <= 1)