简化覆盖重复行的 UNION 查询
Simplify UNION query that overwrites duplicate rows
create table sections(
id serial,
section_name char(255) not null,
version_id int not null
);
create table section_versions(
id int primary key not null,
version_name char(255) not null
);
insert into section_versions(id, version_name)
values (1, 'default'), (2, 'version A'), (3, 'version B');
insert into sections(section_name, version_id)
values ('Toys', 1), ('Animals', 1), ('Cars', 1),
('Toys', 2), ('Animals', 2), ('Instruments', 2),
('Toys', 3);
我需要 select 部分 根据要求 section_version.version_name.
如果version_name是"default",那么查询只需要return全部部分 有 "default" 版本。
但是如果 "version A" 被请求,那么它应该 return 每个 部分 属于 "version A",并添加 "default" 版本中缺少的部分 - 基于 section_name .
请看这个fiddle: http://sqlfiddle.com/#!15/466e1/1/0
这是我想出的:
select * from sections
join section_versions on (section_versions.id = sections.version_id)
where section_versions.version_name = 'default'
and sections.section_name not in (
select sections.section_name from sections
join section_versions on (section_versions.id = sections.version_id)
where section_versions.version_name = 'version A'
)
UNION
select * from sections
join section_versions on (section_versions.id = sections.version_id)
where section_versions.version_name = 'version A'
;
这可能是一次幼稚的尝试,所以我正在寻找更好的解决方案。
最好有一个查询可以处理:
- 仅选择 "default"
- 选择特定版本
- 在不存在默认版本时工作(f.i。如 Instruments)
如果我正确理解您的意图,以下查询应该有所帮助:
select distinct on (sections.section_name) *
from sections
join section_versions on (section_versions.id = sections.version_id)
where
section_versions.version_name in ('default', 'version A')
order by
sections.section_name,
case version_name
when 'default' then 1
else 0
end;
有关详细信息,请参阅 http://www.postgresql.org/docs/current/static/sql-select.html
中的 "DISTINCT Clause" 段落
create table sections(
id serial,
section_name char(255) not null,
version_id int not null
);
create table section_versions(
id int primary key not null,
version_name char(255) not null
);
insert into section_versions(id, version_name)
values (1, 'default'), (2, 'version A'), (3, 'version B');
insert into sections(section_name, version_id)
values ('Toys', 1), ('Animals', 1), ('Cars', 1),
('Toys', 2), ('Animals', 2), ('Instruments', 2),
('Toys', 3);
我需要 select 部分 根据要求 section_version.version_name.
如果version_name是"default",那么查询只需要return全部部分 有 "default" 版本。
但是如果 "version A" 被请求,那么它应该 return 每个 部分 属于 "version A",并添加 "default" 版本中缺少的部分 - 基于 section_name .
请看这个fiddle: http://sqlfiddle.com/#!15/466e1/1/0
这是我想出的:
select * from sections
join section_versions on (section_versions.id = sections.version_id)
where section_versions.version_name = 'default'
and sections.section_name not in (
select sections.section_name from sections
join section_versions on (section_versions.id = sections.version_id)
where section_versions.version_name = 'version A'
)
UNION
select * from sections
join section_versions on (section_versions.id = sections.version_id)
where section_versions.version_name = 'version A'
;
这可能是一次幼稚的尝试,所以我正在寻找更好的解决方案。
最好有一个查询可以处理:
- 仅选择 "default"
- 选择特定版本
- 在不存在默认版本时工作(f.i。如 Instruments)
如果我正确理解您的意图,以下查询应该有所帮助:
select distinct on (sections.section_name) *
from sections
join section_versions on (section_versions.id = sections.version_id)
where
section_versions.version_name in ('default', 'version A')
order by
sections.section_name,
case version_name
when 'default' then 1
else 0
end;
有关详细信息,请参阅 http://www.postgresql.org/docs/current/static/sql-select.html
中的 "DISTINCT Clause" 段落