Как удалить дублирующиеся строки SQL на основе 1 столбца, сравнивая 2 разных столбца даты?

#sql #sql-server

#sql #sql-server

Вопрос:

У меня есть запрос, который объединяет несколько таблиц / представлений и отображает строки, которые идентифицируются столбцом с именем VIN. Я хочу показывать VIN только один раз на основе самой последней даты из 2 разных полей даты (ДАТА ОТКРЫТИЯ И ДАТА ВЫСТАВЛЕНИЯ СЧЕТА), ЕСЛИ обе даты имеют значение.

Если дата счета равна нулю, покажите строку, в которой указана самая последняя открытая дата для этого VIN. Например, если у меня есть 3 строки для VIN = ‘XY123456’ и

Строка 1 показывает дату открытия 3/1/2019 и дату счета NULL, и

Строка 2 показывает дату открытия 15.03.2019 и дату выставления счета 28.03.2019, и

Строка 3 показывает дату открытия 4/1/2019 и дату выставления счета 4/5/2019,

Я хочу вернуть строку 1, поскольку дата выставления счета равна нулю, и это самая последняя открытая дата для этого VIN.

Если бы в строке 1 была указана дата счета, мы бы вернули строку с самой последней датой из любого столбца даты.

Я безуспешно пробовал ELSE clause и COALASCE. Я также попытался выполнить подзапрос, чтобы использовать MAXDATE.

 SELECT RO.[RepairOrderID]
      ,RO.[CompanyName]
      ,CUS.CustomerKey
      ,UN.UnitNumber AS 'UNIT #'
      ,ISNULL(UC.[Tag #],'') AS 'S #'
      ,UN.Year
      ,UN.Make
      ,UN.Model
      ,UN.VIN
      ,ROS.[RepairOrderStatus] AS 'STATUS'
      ,RO.RepairOrderNumber AS 'RO #'
      ,CONVERT(VARCHAR(2),DATEPART(month, RO.[OpenDate])) 
         '/'  CONVERT(VARCHAR(2),DATEPART(DAY, RO.[OpenDate])) 
         '/'   CONVERT(VARCHAR(4),DATEPART(YEAR, RO.[OpenDate])) 
         'OPEN DATE'
     ,CONVERT(VARCHAR(2),DATEPART(month, ROI.InvoiceDate)) 
         '/'  CONVERT(VARCHAR(2),DATEPART(DAY, ROI.InvoiceDate)) 
         '/'   CONVERT(VARCHAR(4),DATEPART(YEAR, ROI.InvoiceDate)) 
         'INVOICE DATE'
  FROM [ProfitMaster].[dbo].[RepairOrder] RO with (nolock)
  INNER JOIN [ProfitMaster].[dbo].[vwAC_SSR_Customer] CUS with (nolock)
  ON CUS.CustomerID = RO.CustomerID
  INNER JOIN [ProfitMaster].[dbo].[RepairOrderStatus] ROS with (nolock)
  ON ROS.RepairOrderStatusID = RO.RepairOrderStatusID
  LEFT OUTER JOIN [ProfitMaster].[dbo].[RepairOrderInvoice] ROI with (nolock)
  ON ROI.RepairOrderID = RO.RepairOrderID
  LEFT OUTER JOIN [ProfitMaster].[dbo].[vwSR_SSR_Unit] UN with (nolock)
  ON UN.UnitInventoryID = RO.UnitInventoryID
  LEFT OUTER JOIN [ProfitMaster].[dbo].[vwSR_SSR_UnitCharacteristics] UC with (nolock)
  ON UC.UnitInventoryID = Ro.UnitInventoryID
  WHERE ((ROS.RepairOrderStatus IN ('OPEN')
  OR (ROS.RepairOrderStatus = 'QUOTE' AND RO.OpenDate >= (getDate()- 90)))
  OR (ROS.RepairOrderStatus = 'INVOICED' AND ROI.InvoiceDate > '2019-01-01 00:00:00.000'))
  AND (CUS.InternalAccount = '0' AND CUS.InternalLRCustomer = '0')
  

Пример результатов:

введите описание изображения здесь

Комментарии:

1. Если вы добавите образец данных (не изображение) и желаемый результат (не изображение), вы поможете людям, которые хотят помочь вам, и это прояснит, чего вы хотите.

2. Кажется, вы хотите вычислить row_number следующим образом Row_Number() Over (PARTITION BY VIN ORDER BY CASE WHEN InvoiceDate IS NULL THEN 0 ELSE 1 END, OpenDate DESC)

3. @StepUp — Картинка подходит для примера результатов. Не уверен, почему это имеет значение.

4. @dnoeth — спасибо за предложение. Я пытался, но, похоже, это работает некорректно. Для всех строк с одинаковым VIN не берется самая высокая дата из обеих дат.

5. Затем добавьте образцы данных (DDL amp; Inserts), охватывающие все возможные комбинации и ожидаемый результат (с объяснением)