Более быстрый SQL-запрос, чтобы сделать это - PullRequest
1 голос
/ 30 июня 2011

У меня есть SP и UDF, которые приносят мне итоги.Но я знаю, что существует запрос COUNT CASE WHEN, позволяющий получить итоги за один раз.Может ли кто-нибудь помочь мне в этом отношении?Мой текущий запрос - просто избыточная пауза.

ALTER PROCEDURE [dbo].[GetMailBasketsForLocums] 
AS
BEGIN
    SET NOCOUNT ON;
    SET FMTONLY OFF;
    SET DATEFORMAT DMY; 

SELECT DISTINCT Locum.OID,
                                    Locum.FirstName + ' ' + Locum.LastName AS Name,
                                    dbo.GetMailBasketTotalsForLocums(MailBasket.LocumId, 1) AS BookingsConfirmed,
                                    dbo.GetMailBasketTotalsForLocums(MailBasket.LocumId, 3) AS BookingsCancelled,
                                    dbo.GetMailBasketTotalsForLocums(MailBasket.LocumId, 5) AS BookingsSwitched,
                                    (dbo.GetMailBasketTotalsForLocums(MailBasket.LocumId, 1) + 
                                     dbo.GetMailBasketTotalsForLocums(MailBasket.LocumId, 3) + 
                                     dbo.GetMailBasketTotalsForLocums(MailBasket.LocumId, 5)) AS Total
    FROM   MailBasket INNER JOIN
                 Locum
                 ON Locum.OID = MailBasket.LocumID
    WHERE  MailBasket.IsSent = 0
                 AND MailBasket.MailTypeID IN (1, 3, 5);
END

И

ALTER FUNCTION [dbo].[GetMailBasketTotalsForLocums] 
(
    @LocumID BIGINT, 
    @MailTypeID INT
)
RETURNS int
AS
BEGIN   
    DECLARE @Result int

    SELECT @Result = COUNT(MailBasket.OID)
    FROM   MailBasket
    WHERE  MailBasket.MailTypeID = @MailTypeID
                 AND MailBasket.LocumID = @LocumID
                 AND MailBasket.IsSent = 0;

    RETURN @Result

END

С уважением.

Ответы [ 3 ]

2 голосов
/ 30 июня 2011
SELECT
    DISTINCT Locum.OID,
     Locum.FirstName + ' ' + Locum.LastName AS Name,
     COUNT(CASE WHEN MailBasket.MailTypeID = 1 THEN 1 ELSE NULL END) AS BookingsConfirmed,
     COUNT(CASE WHEN MailBasket.MailTypeID = 3 THEN 1 ELSE NULL END) AS BookingsCancelled,
     COUNT(CASE WHEN MailBasket.MailTypeID = 5 THEN 1 ELSE NULL END) AS BookingsSwitched,
     COUNT(*) AS Total
FROM
    MailBasket INNER JOIN
             Locum
             ON Locum.OID = MailBasket.LocumID
WHERE  MailBasket.IsSent = 0
             AND MailBasket.MailTypeID IN (1, 3, 5);

COUNT игнорирует NULL для условного подсчета работ

Вы также можете использовать SUM

SUM(CASE WHEN MailBasket.MailTypeID = 5 THEN 1 ELSE 0 END)
1 голос
/ 30 июня 2011

Вы можете использовать case внутри sum и группу в записях Locum:

select
  Locum.OID,
  Locum.FirstName + ' ' + Locum.LastName AS Name,
  sum(case when MailBasket.MailTypeID = 1 then 1 else 0 end) as BookingsConfirmed,
  sum(case when MailBasket.MailTypeID = 3 then 1 else 0 end) as BookingsCancelled,
  sum(case when MailBasket.MailTypeId = 5 then 1 else 0 end) as BookingsSwitched,
  count(*) as Total
from
  MailBasket
  inner join Locum on Locum.OID = MailBasket.LocumID
where
  MailBasket.IsSent = 0
  and MailBasket.MailTypeID IN (1, 3, 5)
group by
  Locum.OID, Locum.FirstName, Locum.LastName
1 голос
/ 30 июня 2011

Попробуйте это:

SELECT DISTINCT Locum.OID, Locum.FirstName + ' ' + Locum.LastName AS Name,
       COUNT(CASE WHEN MailBasket.MailTypeID = 1 THEN MailBasket.MailTypeID END) as BookingsConfirmed,
       COUNT(CASE WHEN MailBasket.MailTypeID = 3 THEN MailBasket.MailTypeID END) as BookingsCancelled,
       COUNT(CASE WHEN MailBasket.MailTypeID = 5 THEN MailBasket.MailTypeID END) as BookingsSwitched,
       COUNT(*) as TOTAL
FROM   MailBasket INNER JOIN
             Locum
             ON Locum.OID = MailBasket.LocumID
WHERE  MailBasket.IsSent = 0
             AND MailBasket.MailTypeID IN (1, 3, 5);
...