У меня есть две связанные таблицы, как показано ниже.
Главный стол:
Подробная таблица:
Емкость на каждый день будет сохранена несколько раз как редакция. В какой-то день будет 1 ревизия, в какой-то день 3, в зависимости от количества сохраненных данных.
Теперь мне нужно взять данные из этих двух таблиц в одном запросе с наибольшей редакцией за каждый день. Ожидается 12 строк данных за 3 существующих дня в выбранном месяце.
Я написал запрос ниже
select a1.wdcm_date as wdcm_date, c1.wdcd_block_no as wdcd_block_no, c1.wdcd_capacity as wdcd_capacity,
c1.wdcd_approval as wdcd_approval, a1.wdcm_revision_no as wdcm_revision_no
from wb_declared_capacity_master a1, wb_declared_capacity_detail c1
where a1.wdcm_internal_id = c1.wdcd_ref_id and to_char(a1.wdcm_date,'MM yyyy')='01 2022'
and wdcm_revision_no = (select max(wdcm_revision_no) from wb_declared_capacity_master where to_char(wdcm_date,'MM yyyy')='01 2022')
Это возвращает только данные с датами версии 3.
Мой ожидаемый результат должен быть
Как получить все 12 строк (все часы для каждой соответствующей версии)?
Ваш подзапрос возвращает только один номер редакции, а не разные номера для каждой даты.
Вам нужен «коррелированный» подзапрос, где подзапрос ссылается на исходное значение во внешнем запросе...
Кроме того, действительно не используйте ,
для соединений, которые с 1992 года заменены синтаксисом ANSI!
Наконец, не используйте бессмысленные псевдонимы, такие как a1, c1 и т. д. Это усложняет чтение кода, а не облегчает его. Псевдонимы должны иметь смысл.
SELECT
cm.wdcm_date as wdcm_date,
cd.wdcd_block_no as wdcd_block_no,
cd.wdcd_capacity as wdcd_capacity,
cd.wdcd_approval as wdcd_approval,
cm.wdcm_revision_no as wdcm_revision_no
FROM
wb_declared_capacity_master AS cm
INNER JOIN
wb_declared_capacity_detail AS cd
ON cd.wdcd_ref_id = cm.wdcm_internal_id
WHERE
to_char(cm.wdcm_date,'MM yyyy')='01 2022'
AND
cm.wdcm_revision_no = (
SELECT MAX(wdcm_revision_no)
FROM wb_declared_capacity_master
WHERE wdcm_date = cm.wdcm_date
)
Еще один случай, который проще и быстрее с DISTINCT ON
:
SELECT m.date, d.hour, d.capacity, m.rev
FROM (
SELECT DISTINCT ON (date) -- simple & fast
id, date, rev
FROM master
WHERE date >= '2022-01-01' -- ! sargable = faster
AND date < '2022-01-02' -- !
ORDER BY date, rev DESC
) m
LEFT JOIN detail d USING (id)
ORDER BY date, hour;
Видеть:
И избегайте выражений в столбцах перед фильтрацией, как чумой.to_char(date,'MM yyyy') = '01 2022')
стоит очень дорого. Прежде чем применить фильтр, его необходимо вычислить для каждой строки таблицы. Используйте фильтр «sargable». Гораздо быстрее, особенно с применимым индексом, но и без него. Связанный:
Тонкие детали: я использую LEFT JOIN
, чтобы сохранить в результате каждый квалификационный день, даже если детали отсутствуют. Это может быть возможно или невозможно с вашей моделью данных. Но в любом случае не повредит.
Почему имена столбцов в вашем запросе не совпадают с именами столбцов в ваших таблицах?