сравнить все данные в каждом столбце в mssql

#sql #sql-server #count #pivot #case

#sql #sql-сервер #подсчитать #сводная #случай

Вопрос:

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

   OrderId   Carrier Truck   Trailer
  10001     ABC     TruckA  TrailerA
  10001     ABC     TruckA  TrailerA
  10001     ABC     TruckB  TrailerA
  10001     ABC     TruckC  TrailerB
  10001     ABC     TruckC  TrailerD
  

Вывод моего запроса должен быть однострочным

  OrderId   Carrier Truck   Trailer
 10001     ABC     NULL    NULL
  

Логика должна применяться так, как если бы каждый столбец содержал одно и то же значение, тогда это значение должно быть в этом конкретном столбце, иначе оно было бы нулевым

Я попробовал приведенные ниже запросы, но не получил правильного вывода

   SELECT 
        s.OrderId
       ,LEAD(s.OrderId,1) OVER (ORDER BY t.Code) AS PreviousOrderId
       ,c.LegalName AS CarrierName
       ,LEAD(c.LegalName,1) OVER (ORDER BY t.Code) AS PreviousCarrierName
       ,t.TruckLicensePlate
       ,LEAD(t.TruckLicensePlate,1) OVER (ORDER BY t.Code) AS PreviousTruckLicensePlate
       ,t.TrailerLicensePlate
       ,LEAD(t.TrailerLicensePlate,1) OVER (ORDER BY t.Code) AS PreviousTrailerLicensePlate
    INTO #tempResult
    FROM
       OrderDetails

    SELECT
        CASE WHEN t.OrderId = t.PreviousOrderId 
             THEN t.OrderId ELSE NULL END AS OrderId
        ,CASE WHEN t.CarrierName = t.PreviousCarrierName
             THEN t.CarrierName ELSE NULL END AS CarrierName
        ,CASE WHEN t.TruckLicensePlate = t.PreviousTruckLicensePlate
             THEN t.TruckLicensePlate ELSE NULL END AS TruckLicensePlate
        ,CASE WHEN t.TrailerLicensePlate = t.PreviousTrailerLicensePlate
             THEN t.TrailerLicensePlate ELSE NULL END AS TrailerLicensePlate
    from #tempResult  t
    order by orderid desc
  

Ответ №1:

Логика должна применяться так, как если бы каждый столбец содержал одно и то же значение, тогда это значение должно быть в этом конкретном столбце, иначе оно было бы нулевым

Используйте агрегацию и условную логику. Я считаю, что сравнение min() и max() является прямым подходом:

 select
    orderid,
    case when min(carrier) = max(carrier) then min(carrier) end carrier,
    case when min(truck)   = max(truck)   then min(carrier) end truck,
    case when min(trailer) = max(trailer) then min(carrier) end trailer
from orderdetails
group by orderid
  

Ответ №2:

Похоже, вы могли бы просто использовать CASE with COUNT и MAX :

 SELECT CASE COUNT(DISTINCT OrderID) WHEN 1 THEN MAX(OrderID) END AS OrderID,
       CASE COUNT(DISTINCT Carrier) WHEN 1 THEN MAX(Carrier) END AS Carrier,
       CASE COUNT(DISTINCT Truck) WHEN 1 THEN MAX(Truck) END AS Truck,
       CASE COUNT(DISTINCT Trailer) WHEN 1 THEN MAX(Trailer) END AS Trailer
FROM dbo.YourTable;