Есть ли способ сортировки родительской записи по самой ранней дате, связанной с ее дочерними записями? - PullRequest
0 голосов
/ 12 апреля 2019

У меня есть две таблицы, таблица счетов и таблица рабочих дней.Счета-фактуры имеют много рабочих дней.

Схема рабочего дня имеет:

invoice_id: integer, date: date

И, скажем, на данный момент схема счетов-фактур имеет только идентификатор в таблице.

С моей точки зрения, я хотел бы распечатать все счета, предварительно загруженные со всеми рабочими днями.Для каждого счета должны быть отсортированы рабочие дни детей по дате.И хотя в накладной нет поля даты, мне интересно, можно ли отсортировать накладные по самой ранней дате среди всех соответствующих рабочих дней детей?

Цель состоит в том, чтобы создать представлениеэто выглядело бы примерно так:

Invoice date range: Jan 02, 2019 - Jan 03, 2019
Workdays: 
Jan 02, 2019
Jan 03, 2019

Invoice date range: Jan 05, 2019 - Jan 06, 2019
Workdays:
Jan 05, 2019
Jan 06, 2019

Я использую запрос, подобный следующему: выберите * из рабочих дней внутреннего объединения счетов-фактур в рабочие дни.invoice_id = invoice.id порядок по рабочим дням

Но можно выставлять счета не по порядку, потому что порядок счетов не указан.Я не знаю другого способа указать порядок сортировки в счете-фактуре без кэширования самого раннего рабочего дня.даты в родительский элемент (счет-фактура) в новом столбце и последующей сортировки по этому дополнительному столбцу.

Обновление:Я использую Postgres и MySQL.Под «представлением» я не имею в виду представление базы данных (материализованное), я имею в виду модель, представление, контроллер, слой представления.

1 Ответ

0 голосов
/ 12 апреля 2019

Что-то вроде:

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)

Если вы хотите получить своих родителей-детей за один прием в оба конца, используйте возможности 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, вам нужно вручную сделать запрос минимизировать количество обращений к серверу.

Если вы хотите использовать все возможности 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');
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...