Альтернативы объединению SQL - PullRequest
0 голосов
/ 02 мая 2019

У меня есть следующий сценарий SQL, в настоящее время он отображает количество строк за определенный промежуток времени. Например. За 15 минут до & 15 минут после заданного времени, за 30 минут до & 30 минут после времени и т. Д. Он работает нормально, но мне нужно изменить это для объединения с точки зрения производительности. Любые идеи о других подходах, как я могу достичь этого с помощью одного выбора / таблицы?

DECLARE @GameNumber int
DECLARE @EventType int

SET @GameNumber = 116
SET @EventType = 1

SELECT 'Between -120 mins and -90 mins' as TimePeriod
      ,COUNT(*) 
FROM attendance ta
LEFT OUTER JOIN SubStations sub
ON TA_ServiceNumber = sub.ServiceNumber
AND TA_DoorNumber = sub.DoorNumber
INNER JOIN [dbo].[Products] pro
ON ta.TA_GameNumber = pro.prd_GameNumber
INNER JOIN dbo.producttypes prot
ON ta.Eventtype = prot.PRD_TypeID AND @EventType = prot.PRD_EventTypeID

WHERE GameNumber = @GameNumber
AND EventType = @EventType
AND ta.TA_TimeAndDate BETWEEN DATEADD(minute, -120, pro.GameTime) AND DATEADD(minute, -90, pro.GameTime)

UNION ALL

SELECT 'Between -90 mins and -60 mins' as TimePeriod
      ,COUNT(*) AS Flow
FROM attendance ta
INNER JOIN TA_OperationCode toc
ON ta.TA_OperationCode = toc.OperationCode
LEFT OUTER JOIN SubStations sub
ON TA_ServiceNumber = sub.ServiceNumber
AND TA_DoorNumber = sub.DoorNumber
INNER JOIN [dbo].[Products] pro
ON ta.TA_GameNumber = pro.prd_GameNumber
INNER JOIN dbo.producttypes prot
ON ta.TA_Eventtype = prot.PRD_TypeID AND @EventType = prot.PRD_EventTypeID

WHERE GameNumber = @GameNumber
AND EventType = @EventType 
AND ta.TA_TimeAndDate BETWEEN DATEADD(minute, -90, pro.GameTime) AND DATEADD(minute, -60, pro.GameTime)

UNION ALL

SELECT 'Between -60 mins and -45 mins' as TimePeriod
      ,COUNT(*) AS Flow
FROM attendance ta
INNER JOIN TA_OperationCode toc
ON ta.TA_OperationCode = toc.OperationCode
LEFT JOIN SubStationssub
ON TA_ServiceNumber = sub.ServiceNumber
AND TA_DoorNumber = sub.DoorNumber
INNER JOIN [dbo].[Products] pro
ON ta.TA_GameNumber = pro.prd_GameNumber
INNER JOIN dbo.producttypes prot
ON ta.TA_Eventtype = prot.PRD_TypeID AND @EventType = prot.PRD_EventTypeID

WHERE GameNumber = @GameNumber
AND EventType = @EventType
AND ta.TA_TimeAndDate BETWEEN DATEADD(minute, -60, pro.GameTime) AND DATEADD(minute, -45, pro.GameTime)

Ответы [ 2 ]

2 голосов
/ 02 мая 2019

Используйте GROUP BY с выражением CASE:

SELECT v.TimePeriod, COUNT(*) 
FROM attendance ta LEFT OUTER JOIN
     SubStations sub
     ON TA_ServiceNumber = sub.ServiceNumber AND
        TA_DoorNumber = sub.DoorNumber INNER JOIN
        [dbo].[Products] pro
        ON ta.TA_GameNumber = pro.prd_GameNumber INNER JOIN 
        dbo.producttypes prot
        ON ta.Eventtype = prot.PRD_TypeID AND
        @EventType = prot.PRD_EventTypeID CROSS APPLY
        (VALUES (CASE WHEN ta.TA_TimeAndDate BETWEEN DATEADD(minute, -120, pro.GameTime) AND DATEADD(minute, -90, pro.GameTime)
                      THEN 'Between -90 mins and -60 mins'
                      WHEN ta.TA_TimeAndDate BETWEEN DATEADD(minute, -90, pro.GameTime) AND DATEADD(minute, -60, pro.GameTime)
                      THEN 'Between -90 mins and -60 mins'
                      . . .
                 END)
        ) v(TimePeriod)
WHERE GameNumber = @GameNumber AND EventType = @EventType
GROUP BY v.TimePeriod
ORDER BY MIN(ta.TA_TimeAndDate);
1 голос
/ 02 мая 2019

почему бы не просто GROUP BY The Case Statement: EG

select 
case 
when ta.TA_TimeAndDate BETWEEN DATEADD(minute, -120, pro.GameTime) AND DATEADD(minute, -90, pro.GameTime)
 then 'Between -120 mins and -90 mins' 
when ta.TA_TimeAndDate BETWEEN DATEADD(minute, -90, pro.GameTime) AND DATEADD(minute, -60, pro.GameTime)
 then 'Between -90 mins and -60 mins'
when ta.TA_TimeAndDate BETWEEN DATEADD(minute, -60, pro.GameTime) AND DATEADD(minute, -45, pro.GameTime)
 then 'Between -60 mins and -45 mins'
else ''
END 

 as TimePeriod,
 count(*) as Flow


 FROM attendance ta
INNER JOIN TA_OperationCode toc
ON ta.TA_OperationCode = toc.OperationCode
LEFT OUTER JOIN SubStations sub
ON TA_ServiceNumber = sub.ServiceNumber
AND TA_DoorNumber = sub.DoorNumber
INNER JOIN [dbo].[Products] pro
ON ta.TA_GameNumber = pro.prd_GameNumber
INNER JOIN dbo.producttypes prot
ON ta.TA_Eventtype = prot.PRD_TypeID AND @EventType = prot.PRD_EventTypeID

WHERE GameNumber = @GameNumber
AND EventType = @EventType 

AND ta.TA_TimeAndDate BETWEEN DATEADD(minute, -120, pro.GameTime) AND DATEADD(minute, -45, pro.GameTime)

group by
case 
when ta.TA_TimeAndDate BETWEEN DATEADD(minute, -120, pro.GameTime) AND DATEADD(minute, -90, pro.GameTime)
 then 'Between -120 mins and -90 mins' 
when ta.TA_TimeAndDate BETWEEN DATEADD(minute, -90, pro.GameTime) AND DATEADD(minute, -60, pro.GameTime)
 then 'Between -90 mins and -60 mins'
when ta.TA_TimeAndDate BETWEEN DATEADD(minute, -60, pro.GameTime) AND DATEADD(minute, -45, pro.GameTime)
 then 'Between -60 mins and -45 mins'
else ''
END

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

AND (toc.OperationCode is not null or ta.TA_TimeAndDate > DATEADD(minute, -90, pro.GameTime))

`

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...