(Advantage Database Server) У меня есть таблица поставщиков услуг, которые для целей аудита никогда не удаляются. У них есть дата начала и дата окончания; в случае изменений, таких как имя или адрес, существующая строка заканчивается, создается новая строка, и для измененных данных назначается новая дата начала.Соответствие только одной определенной строке в JOIN, где многие существуют
Во время обработки платежей этим провайдерам мне нужна сводная страница с указанием имени поставщика, адреса, идентификатора (ProvID) и общей суммы платежа. Это делается в довольно простом запросе с помощью SUM() и GROUP BY.
Проблема возникает, если для указанного идентификатора поставщика имеется две или более строк. Я получаю дубликаты строк (это может привести к нескольким платежам этому провайдеру, если они не пойманы).
Моя первая мысль была использовать что-то (уродливый, но работает достаточно быстро), как подзапрос:
SELECT ... FROM service s
INNER JOIN provider p ON p.ProvID = s.ProvID
AND (p.EndDate IS NULL or p.EndDate = (SELECT Max(EndDate) FROM
provider lu WHERE lu.ProvID = s.ProvID))
К сожалению, это все-таки в конечном итоге найти два ряда; одна строка для NULL EndDate и одна для MAX (EndDate).
я справиться с этим в других случаях (например., Размещение надлежащего Provid для услуг, предоставляемых на определенную дату) с использованием
p.EndDate is null or (s.ServiceDate BETWEEN p.StartDate AND p.EndDate)
К сожалению, так как запрос проблемы является GROUP BY с агрегатом, то дата службы недоступна.
Любые предложения?
EDIT: Я ищу либо строку с NULL EndDate, если она существует, либо строка с Max (EndDate), если строка NULL не существует. Это касается случая, например, когда вчера поставщик был прекращен, но работал на прошлой неделе, и мы будем платить им на следующей неделе.
Я принимаю этот ответ, потому что он довольно гладкий, и он немного быстрее, чем ответ Niedmeddine NOT EXISTS (но только незначительно из-за хорошего выбора индекса). Спасибо, Кип. :-) –
Просто слился в мою кодовую базу и протестирован против фактических данных. Работает 100%, без заметной потери производительности. Еще раз спасибо, Кип! ПРИМЕЧАНИЕ ДЛЯ ДРУГИХ ПОЛЬЗОВАТЕЛЕЙ ADS: вызовы COALESCE() требуют одно дополнение: измените оба из них на COALESCE (EndDate, CAST ('2037-01-01' AS SQL_DATE)), поскольку ADS не выполняет автоматическое преобразование с даты литералы, как и другие базы данных. –
@Ken White: Если у вас более одной строки с конечной датой NULL, вы получите больше одной строки в качестве результата. Я полагаю, что это будет считаться поврежденными данными в вашей схеме. – Kip