Доступ к оператору SQL: если ни одна запись не является действительной, вернуть последнюю - PullRequest
0 голосов
/ 23 февраля 2019

Я пытаюсь получить инструкцию SQL, которая решает следующую проблему.

У меня есть таблица «календарь», которая включает в себя только один столбец «дата».Эта таблица содержит 12 записей для каждого месяца в 2019 году (01.31.2019, 02.2.201.2019 и т. Д.).Вторая таблица «значения» (которую я получаю из системы ERP) имеет три столбца: «от», «до» и «сумма» (например, 01.01.2019, 06.30.2019, 50 и 08.01.2019, 08.31.2019,100).

У меня есть простое утверждение, которое проверяет, какая запись действительна на конкретную дату:

SELECT Calendar.Date, Values.From, Values.To, Values.Amount
FROM Calendar, [Values]
WHERE Calendar.Date >= Values.From 
  AND Calendar.Date <= Values.To;

Нет действительной записи (в таблице "значения") для июля,Сентябрь, октябрь, ноябрь и декабрь.

В случае отсутствия действительной записи следует использовать последнюю запись.В июле это будет 50, а в сентябре, октябре ... это будет 100.

Я пробовал подзапрос и оставлял объединения, но я так и не получил желаемый результат.

Есть у кого-нибудь идея?или лучше решение этой проблемы.Я ценю любую поддержку

Ответы [ 2 ]

0 голосов
/ 23 февраля 2019

Вы можете сделать это с помощью LEFT JOIN и подзапроса, чтобы получить последнюю сумму:

SELECT c.Date, v.From, v.To, 
Nz(
  v.Amount, 
  (SELECT MAX([Values].Amount) FROM [Values] WHERE [Values].From = 
    (SELECT MAX([Values].From) FROM [Values] WHERE [Values].From <= c.Date))
) AS Amount
FROM Calendar AS c LEFT JOIN [Values] AS v
ON c.Date>=v.From AND c.Date<=v.To;
0 голосов
/ 23 февраля 2019

Я думаю, что вы ищете дополнительное объединение в таблице Values, которое вернет последнюю запись перед текущей датой.Если первая (LEFT) JOIN не удалась, вы можете использовать результат, возвращенный второй.

Чтобы найти последнюю запись до текущей даты, мы можем использовать условие NOT EXISTS с коррелированным подзапросом.

SELECT 
    c.Date, 
    Nz(v.From, v1.From) AS [From], 
    Nz(v.To, v1.To) AS [To], 
    Nz(v.Amount, v1.Amount) AS [Amount]
FROM Calendar AS c
LEFT JOIN [Values] AS v 
    ON c.Date >= v.From AND c.Date <= v.To
LEFT JOIN [Values] AS v1 
    ON v1.To < c.Date
    AND NOT EXISTS (
        SELECT 1 FROM [Values] v2 WHERE v2.To < c.Date AND v2.To > v1.To
    )

PS: в SQL долгое время было хорошей практикой избегать старой школы, неявных JOIN с и всегда использовать явные JOIN с.

...