Хорошо, давайте доработаем ваш SQL-запрос, чтобы получить последнюю изменённую цену и цену клиента для каждой даты и артикулов. Для этого необходимо использовать подзапросы, которые будут находить самые последние изменения цен для данных дат.
Ваш запрос уже содержит постепенно включающие элементы для получения нужной информации, и нужно добавить логику выбора последней цены на каждую дату. Вот переработанный запрос:
```sql
WITH ds AS (
SELECT generate_series(
'2023-01-01'::date,
'2025-12-31'::date,
'1 day'::interval
)::date AS date
),
items AS (
SELECT DISTINCT article FROM ozon.items
UNION
SELECT DISTINCT article FROM wildberries.items
UNION
SELECT DISTINCT article FROM yandex.items
UNION
SELECT DISTINCT article FROM sber.items
),
all_combinations AS (
SELECT ds.date, items.article
FROM ds
CROSS JOIN items
),
ozon_client_prices AS (
SELECT
date(updated_at) AS date,
article,
value AS client_price
FROM ozon._history_of_client_prices
),
ozon_self_prices AS (
SELECT
date(updated_at) AS date,
article,
value AS self_price
FROM ozon._history_of_self_prices
),
latest_client_prices AS (
SELECT
ac.date,
ac.article,
ocp.client_price,
ROW_NUMBER() OVER (PARTITION BY ac.article ORDER BY ocp.date DESC) AS rn
FROM all_combinations ac
LEFT JOIN ozon_client_prices ocp ON ac.date >= ocp.date
),
latest_self_prices AS (
SELECT
ac.date,
ac.article,
osp.self_price,
ROW_NUMBER() OVER (PARTITION BY ac.article ORDER BY osp.date DESC) AS rn
FROM all_combinations ac
LEFT JOIN ozon_self_prices osp ON ac.date >= osp.date
)
SELECT
ac.date,
ac.article,
coalesce(lcp.client_price, 0) AS client_price,
coalesce(lsp.self_price, 0) AS self_price
FROM all_combinations ac
LEFT JOIN latest_client_prices lcp ON ac.date = lcp.date AND ac.article = lcp.article AND lcp.rn = 1
LEFT JOIN latest_self_prices lsp ON ac.date = lsp.date AND ac.article = lsp.article AND lsp.rn = 1
ORDER BY ac.date, ac.article;
```
### Объяснение запроса:
1. **Образование дат**: `ds` - образует серию дат от `'2023-01-01'` до `'2025-12-31'`.
2. **Артикулы**: `items` - объединяет все уникальные артики из разных таблиц.
3. **Все комбинации**: `all_combinations` - создается кросс-продукт всех дат и артикулов.
4. **Цены клиентов и собственные цены**: `ozon_client_prices` и `ozon_self_prices` - выбирают данные цен с их обновлениями.
5. **Последние цены**: `latest_client_prices` и `latest_self_prices` - используют `ROW_NUMBER()` для выбора последней цены до (или на) каждой из дат.
6. **Финальный выбор**: На выходе мы выбираем дату, артикул, и цены, используя `LEFT JOIN` для связки каждой даты и артикула с их последними ценами.
Таким образом, вы получите таблицу с последней ценой для каждого артикула на каждую дату.
Обратите внимание, что если у вас могут отсутствовать цены на определённые даты, результат для этих дат будет иметь `NULL` значения, которые мы заменяем на 0 с помощью функции `coalesce`.
Этот запрос будет работать для PostgreSQL. Если будете его тестировать, убедитесь, что типы данных, такие как `updated_at` и другие, соответствуют вашим данным.