类似:
select
i.id, i.comment,
min(wd.date) as invoice_range_from, max(wd.date) as invoice_range_to
from invoice i
left join workdays wd on i.id = wd.invoice_id
group by i.id
order by min(wd.date), max(wd.date)
如果您想在一次服务器往返中检索您的父子节点,请使用您的 RDBMS 的 JSON 或 XML 功能,特别是如果您的客户端应用程序无论如何都会使用 JSON,您可以使用以下方法。例如,
现场测试:https://dbfiddle.uk/?rdbms=postgres_11&fiddle=0b1ce002c4380a3542387209c3c43fae
select
i.id, i.comment,
min(wd.date) as invoice_from, max(wd.date) as invoice_to,
json_agg(json_build_object('date', wd.date)) as workdays_data
from invoice i
left join workdays wd on i.id = wd.invoice_id
group by i.id
order by min(wd.date), max(wd.date)
输出:
id comment invoice_from invoice_to workdays_data
1 Hello 2019-01-02 2019-01-03 [{"date" : "2019-01-02"}, {"date" : "2019-01-03"}]
2 Hola 2019-01-05 2019-01-06 [{"date" : "2019-01-05"}, {"date" : "2019-01-06"}]
否则,您将不得不使用 ORM 的批处理功能。如果没有功能强大的 ORM,则需要手动使查询最小化服务器往返。
如果想全力以赴地使用 RDBMS 的 JSON 功能一次性渲染树状数据,您可以:)
现场测试:https://dbfiddle.uk/?rdbms=postgres_11&fiddle=1ed3105719ed033ba568e01b3d97c234
with a as
(
select
i.id, i.comment,
min(wd.date) as invoice_range_from, max(wd.date) as invoice_range_to,
json_agg(json_build_object('date', wd.date)) as workdays_data
from invoice i
left join workdays wd on i.id = wd.invoice_id
group by i.id
order by min(wd.date), max(wd.date)
)
select json_agg(a.*) from a;
输出:
[
{
"id": 1,
"comment": "Hello",
"invoice_range_from": "2019-01-02",
"invoice_range_to": "2019-01-03",
"workdays_data": [
{
"date": "2019-01-02"
},
{
"date": "2019-01-03"
}
]
},
{
"id": 2,
"comment": "Hola",
"invoice_range_from": "2019-01-05",
"invoice_range_to": "2019-01-06",
"workdays_data": [
{
"date": "2019-01-05"
},
{
"date": "2019-01-06"
}
]
}
]
架构:
create table invoice
(
id int primary key,
comment text not null
);
create table workdays
(
invoice_id int not null references invoice(id),
id int not null generated by default as identity primary key,
date date not null
);
insert into invoice(id, comment) values
(1, 'Hello'),
(2, 'Hola');
insert into workdays(invoice_id, date) values
(1, '2019-1-2'),
(1, '2019-1-3'),
(2, '2019-1-5'),
(2, '2019-1-6');