Как рассчитать разницу в днях, используя более одной даты?

У меня есть следующая таблица:

Таблица А:

ИДЕНТИФИКАТОР Дата сделки Cancel_Flag 1 2014-02-18 00:00:00.000 Нет 1 2014-02-18 00:00:00.000 Нет 1 2014-02-19 00:00:00.000 Да 1 20.05.2014 00:00:00.000 Нет 1 2014-05-21 00:00:00.000 Нет 1 2014-05-22 00:00:00.000 Да 1 2014-05-23 00:00:00.000 Нет

Я хочу, чтобы вывод выглядел так:

  1. Вычислите разницу в днях между transaction_date(где cancel_flag = No) и transaction_date(где cancel_flag = Yes).

  2. Если имеется более 1 cancel_flag = Yes. Используемая разница в днях должна быть минимальной.

ИДЕНТИФИКАТОР Дата сделки Cancel_Flag Дней_С_Отмены 1 2014-02-18 00:00:00.000 Нет -1 1 2014-02-18 00:00:00.000 Нет -1 1 2014-02-19 00:00:00.000 Да 0 1 20.05.2014 00:00:00.000 Нет 1 1 2014-05-21 00:00:00.000 Нет -1 1 2014-05-22 00:00:00.000 Да 0 1 2014-05-22 00:00:00.000 Нет +1 1 2014-05-23 00:00:00.000 Нет +2

Заранее спасибо,

Инструменты для веб-скрапинга с открытым исходным кодом: Python Developer Toolkit
Инструменты для веб-скрапинга с открытым исходным кодом: Python Developer Toolkit
Веб-скрейпинг, как мы все знаем, это дисциплина, которая развивается с течением времени. Появляются все более сложные средства борьбы с ботами, а...
Калькулятор CGPA 12 для семестра
Калькулятор CGPA 12 для семестра
Чтобы запустить этот код и рассчитать CGPA, необходимо сохранить код как HTML-файл, а затем открыть его в веб-браузере. Для этого выполните следующие...
ONLBest Online HTML CSS JAVASCRIPT Training In INDIA 2023
ONLBest Online HTML CSS JAVASCRIPT Training In INDIA 2023
О тренинге HTML JavaScript :HTML (язык гипертекстовой разметки) и CSS (каскадные таблицы стилей) - две основные технологии для создания веб-страниц....
Как собрать/развернуть часть вашего приложения Angular
Как собрать/развернуть часть вашего приложения Angular
Вам когда-нибудь требовалось собрать/развернуть только часть вашего приложения Angular или, возможно, скрыть некоторые маршруты в определенных средах?
Запуск PHP на IIS без использования программы установки веб-платформы
Запуск PHP на IIS без использования программы установки веб-платформы
Установщик веб-платформы, предлагаемый компанией Microsoft, перестанет работать 31 декабря 2022 года. Его закрытие привело к тому, что мы не можем...
Оптимизация React Context шаг за шагом в 4 примерах
Оптимизация React Context шаг за шагом в 4 примерах
При использовании компонентов React в сочетании с Context вы можете оптимизировать рендеринг, обернув ваш компонент React в React.memo сразу после...
0
0
66
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Для каждой записи единственные строки «отмены», которые вас интересуют, — это непосредственно перед или сразу после текущей строки, когда набор данных отсортирован по транзакции_дате. Из-за этого решения с использованием оконных функций кажутся здесь вполне уместными.

Для любой заданной строки вы можете получить дату предыдущей транзакции отмены с помощью

max(Case When Cancel_Flag='Yes' Then transaction_date End)
  Over (Partition By ID Order By Transaction_Date Rows Between Unbounded Preceding And Current Row)

, и дата следующей транзакции отмены с

min(Case When Cancel_Flag='Yes' Then transaction_date End)
  Over (Partition By ID Order By Transaction_Date Rows Between Current Row And Unbounded Following)

Просто используйте каждый в datediff() с текущей датой транзакции строк, и у вас есть два возможных результата, которые вы можете выбрать, чтобы получить окончательный результат.

Select ID,Transaction_Date,Cancel_Flag,
    Case When prior_cancel is null or next_cancel<abs(prior_cancel)
         Then next_cancel Else prior_cancel End as Days_Since_Cancel
From (
    Select A.*,
      datediff(day,Transaction_Date,
        max(Case When Cancel_Flag='Yes' Then transaction_date End)
         Over (Partition By ID Order By Transaction_Date Rows Between Unbounded Preceding And Current Row)
      ) as prior_cancel,
      datediff(day,Transaction_Date,
        min(Case When Cancel_Flag='Yes' Then transaction_date End)
         Over (Partition By ID Order By Transaction_Date Rows Between Current Row And Unbounded Following)
      ) as next_cancel
    From Table_A A
)
Order By ID,Transaction_Date

РЕДАКТИРОВАТЬ ДОПОЛНЕНИЕ Обратите внимание, что вместо min(...) вы можете использовать first_value(... Игнорировать нули), а вместо max(...) вы можете использовать last_value(... Игнорировать нули). Это может быть немного более эффективным, потому что, хотя вы не можете определить минимум и максимум, не исследуя всю рамку окна, теоретически первое и последнее можно определить, не исследуя каждый элемент. Они всегда функционально эквивалентны, если столбец Order By и min/max(столбец) совпадают, в данном случае Transaction_Date.

Спасибо за это Крис! Что делать, если у меня больше 2 cancel_flag = Yes?

Nick Edwards 14.02.2023 08:32

Если вы посмотрите на любую данную запись, ее ближайшая по времени запись об отмене — это либо отмененная непосредственно перед ней по времени, либо та, что сразу после нее по времени. Таким образом, упорядочив список по Transaction_Date, максимальная дата отмененных записей до нее и минимальная дата после нее ближе, чем любая другая запись с cancel_flag='yes'. Так что неважно, сколько раз запись отменили, этот найдет самый близкий.

Chris Maurer 14.02.2023 21:26

Другие вопросы по теме