Вторая самая последняя дата в нескольких внутренних соединениях - PullRequest
1 голос
/ 23 мая 2019

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

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

**Where pet.endtime < (Select max(pet.endtime) From dbo.plannedeventtimeline)**




SELECT Cast(planned.LOCALDAY AS DATE) [Day]
   , actual.Campaign
   , org.Name Organization
   , eAM.EMPLOYEENUMBER SalesID
   , p.LastName + ', ' + p.FirstName Employee
   , DateAdd(HH, planned.tz_offset, planned.min_starttime) PlannedStart
    , DateAdd(HH, planned.tz_offset, actual.min_StartTime) ActualStart
   ,DateAdd(HH, planned.tz_offset, planned.max_endtime) PlannedEnd 
   , DateAdd(HH, planned.tz_offset, actual.max_EndTime) ActualEnd
FROM (
   SELECT orgDay.LOCALDAY
         , pet.WORKRESOURCEID
         , orgDay.ORGANIZATIONID
         , min(pet.Starttime) min_StartTime
         , max(pet.Endtime) max_EndTime     ---This is what I have trouble with---
         , DateDiff(HH, orgDay.StartTime, orgDay.LocalDay) tz_offset
   FROM dbo.PLANNEDEVENTTIMELINE pet
   INNER JOIN dbo.organizationday orgDay
         ON orgDay.ID = pet.ORGANIZATIONDAYID
   WHERE orgDay.LocalDay = CAST(DateAdd(DAY, -1, GETDATE()) as DATE)
   GROUP BY orgday.localday
         , orgday.starttime
         , pet.WORKRESOURCEID
         , orgDay.ORGANIZATIONID
   ) planned
INNER JOIN (
   SELECT spDay.Localday
         , c.Name Campaign
         , aet.EmployeeID
         , min(aet.starttime) min_StartTime
         , max(aet.endtime) max_endtime
   FROM dbo.ACTUALEVENTTIMELINE aet
   LEFT JOIN dbo.ORGANIZATIONDAY spDay
         ON spDay.ID = aet.SPDAYID AND aet.ISPAID != 0
   INNER JOIN dbo.sp sp
         ON sp.sid = spday.SPID
   INNER JOIN dbo.campaign c
         ON c.id = sp.CAMPAIGNID
   WHERE spDay.LocalDay = CAST(DateAdd(DAY, -1, GETDATE()) as DATE)
   GROUP BY spday.localday
         , c.name
         , aet.EMPLOYEEID
   ) AS actual
   ON planned.LOCALDAY = actual.LOCALDAY AND planned.WORKRESOURCEID = actual.EMPLOYEEID
INNER JOIN dbo.ORGANIZATION org
   ON org.id = planned.ORGANIZATIONID
   AND org.Name LIKE '%CPO%'
INNER JOIN dbo.EMPLOYEEAM eam
   ON eam.id = planned.WORKRESOURCEID
INNER JOIN dbo.person p
   ON p.id = eam.personid
ORDER BY 1, 2, 3, 5

Ответы [ 2 ]

0 голосов
/ 24 мая 2019

Рассмотрим это решение с несколькими CTE, в котором запланированные и фактические производные таблицы становятся CTE, а новый оператор date_ranks включает в себя ROWNUMBER() оконную функцию с PARITION BY и ORDER BY.Столбцы разделов отражают GROUP BY столбцов в , запланированных для ранжирования дат заказа в той же группе.

Затем в основном запросе верхнего уровня выполните INNER JOIN, используя date_ranks для тех же столбцов GROUP BY, выбирая только где rank = 2.

WITH planned AS (
   SELECT orgDay.LOCALDAY
         , pet.WORKRESOURCEID
         , orgDay.ORGANIZATIONID
         , min(pet.Starttime) min_StartTime
         , max(pet2.Endtime) max_EndTime     
         , DateDiff(HH, orgDay.StartTime, orgDay.LocalDay) tz_offset
   FROM dbo.PLANNEDEVENTTIMELINE pet
   INNER JOIN dbo.organizationday orgDay
         ON orgDay.ID = pet.ORGANIZATIONDAYID
   WHERE orgDay.LocalDay = CAST(DateAdd(DAY, -1, GETDATE()) as DATE)
   GROUP BY orgday.localday
         , orgday.starttime
         , pet.WORKRESOURCEID
         , orgDay.ORGANIZATIONID
   ),

   actual AS (
   SELECT spDay.Localday
         , c.Name Campaign
         , aet.EmployeeID
         , min(aet.starttime) min_StartTime
         , max(aet.endtime) max_endtime
   FROM dbo.ACTUALEVENTTIMELINE aet
   LEFT JOIN dbo.ORGANIZATIONDAY spDay
         ON spDay.ID = aet.SPDAYID AND aet.ISPAID != 0
   INNER JOIN dbo.sp sp
         ON sp.sid = spday.SPID
   INNER JOIN dbo.campaign c
         ON c.id = sp.CAMPAIGNID
   WHERE spDay.LocalDay = CAST(DateAdd(DAY, -1, GETDATE()) as DATE)
   GROUP BY spday.localday
         , c.name
         , aet.EMPLOYEEID
   ),

   date_ranks AS (
   SELECT  orgday.localday
          , orgday.starttime
          , pet.WORKRESOURCEID
          , orgDay.ORGANIZATIONID
          , pet.Endtime
          , ROW_NUMBER() OVER(PARTITION BY orgday.localday
                                         , orgday.starttime
                                         , pet.WORKRESOURCEID
                                         , orgDay.ORGANIZATIONID
                              ORDER BY pet.Endtime DESC) AS rank
   FROM dbo.PLANNEDEVENTTIMELINE pet
   INNER JOIN dbo.organizationday orgDay
         ON orgDay.ID = pet.ORGANIZATIONDAYID
   WHERE orgDay.LocalDay = CAST(DateAdd(DAY, -1, GETDATE()) as DATE)
   )    

SELECT Cast(planned.LOCALDAY AS DATE) [Day]
   , actual.Campaign
   , org.Name Organization
   , eAM.EMPLOYEENUMBER SalesID
   , p.LastName + ', ' + p.FirstName Employee
   , DateAdd(HH, planned.tz_offset, planned.min_starttime) PlannedStart
   , DateAdd(HH, planned.tz_offset, actual.min_StartTime) ActualStart
   , DateAdd(HH, planned.tz_offset, planned.max_endtime) PlannedEnd 
   , DateAdd(HH, planned.tz_offset, dr.pet.Endtime) Second_Recent_PlannedEnd  -- NEW COLUMN
   , DateAdd(HH, planned.tz_offset, actual.max_EndTime) ActualEnd
FROM planned
INNER JOIN actual
   ON planned.LOCALDAY = actual.LOCALDAY 
  AND planned.WORKRESOURCEID = actual.EMPLOYEEID
INNER JOIN date_ranks dr                                                      -- NEW JOIN
   ON planned.LOCALDAY = dr.LOCALDAY 
  AND planned.WORKRESOURCEID = dr.WORKRESOURCEID
  AND planned.starttime = dr.starttime
  AND planned.ORGANIZATIONID = dr.ORGANIZATIONID
  AND dr.rank = 2
INNER JOIN dbo.ORGANIZATION org
   ON org.id = planned.ORGANIZATIONID
   AND org.Name LIKE '%CPO%'
INNER JOIN dbo.EMPLOYEEAM eam
   ON eam.id = planned.WORKRESOURCEID
INNER JOIN dbo.person p
   ON p.id = eam.personid
ORDER BY 1, 2, 3, 5
0 голосов
/ 23 мая 2019

Можете ли вы проверить замену вашей линии -

 MAX(pet.Endtime) max_EndTime

С -

(
    SELECT MAX(Endtime) 
    FROM PLANNEDEVENTTIMELINE 
    WHERE Endtime < max(pet.Endtime)
) max_EndTime
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...