Почему Over () не работает над суммой столбца? - PullRequest
0 голосов
/ 04 июня 2018

Я пытаюсь получить общую сумму для TotalPrice, но выдает ошибку:

Столбец 'Invoices.ServicePrice' недопустим в списке выбора, потому что это несодержится в статистической функции или в предложении GROUP BY.

ALTER PROCEDURE [dbo].[SalesReport] 

        @FromDate date= '11-May-2018',
        @ToDate date= '05-Jun-2018'

AS
BEGIN
        Set @ToDate= case when @ToDate IS NULL then Convert(varchar(11), getdate(), 106) else @ToDate end

        Select ROW_NUMBER() over (partition by b.BookingID order by b.BookingID) as ID, inv.InvoiceNo, 
        convert(varchar(11),inv.EntryDateTime,106) as EntryDateTime, Count(s.ServiceID) as TotalServices,
        SUM(inv.ServicePrice) as TotalPrice, SUM(inv.ServicePrice) over() as TotalRevenue
        from Invoices inv
        Inner Join Bookings b
        ON b.BookingID= inv.fk_BookingID
        Inner Join ZahidCarWashDB.dbo.Services s
        ON s.ServiceID= inv.fk_ServiceID
        where Convert(varchar(11), inv.EntryDateTime, 106) between @FromDate and @ToDate
        group by convert(varchar(11),inv.EntryDateTime,106), inv.InvoiceNo, b.BookingID



END

Ответы [ 3 ]

0 голосов
/ 04 июня 2018

Смешивание оконной функции с агрегатными функциями является проблемой.Вы могли бы взять другой подход.Как то так:

 SELECT p.id, p.TotalPrice, p.TotalServices
        , SUM(p.TotalPrice) OVER (ORDER BY p.id) AS TotalPriceCumulative
        , SUM(p.TotalServices) OVER (ORDER BY P.id) AS TotalServicesCumulative
 FROM (
 SELECT b.BookingID AS ID -- or row_number() over (order By b.BookingID) AS ID
        , inv.TotalPrice, inv.TotalServices
 FROM Bookings AS b 
 INNER JOIN (SELECT inv1.fk_BookingID, SUM(inv.ServicePrice) as TotalPrice, Count(s.ServiceID) as TotalServices
                FROM Invoices AS inv1
                -- works only if one invoice is released for every invoice
                INNER Join ZahidCarWashDB.dbo.Services s ON s.ServiceID= inv1.fk_ServiceID
                where Convert(varchar(11), inv.EntryDateTime, 106) between @FromDate and @ToDate
             ) AS inv ON b.BookingID= inv.fk_BookingID
 ) AS p
0 голосов
/ 04 июня 2018

Я думаю, что Гордон исправил вашу ошибку.
Вы не должны конвертировать дату в varchar и проводить сравнение.

    Set @ToDate = isnull(@ToDate, getdate());

    Select  ROW_NUMBER() over (partition by b.BookingID order by b.BookingID) as ID, 
            inv.InvoiceNo, 
            convert(varchar(11), inv.EntryDateTime, 106) as EntryDateTime, 
            Count(s.ServiceID)    as TotalServices,
            SUM(inv.ServicePrice) as TotalPrice, 
            SUM(inv.ServicePrice) over() as TotalRevenue
    from Invoices inv
    Inner Join Bookings b
       ON b.BookingID = inv.fk_BookingID
    Inner Join ZahidCarWashDB.dbo.Services s
       ON s.ServiceID = inv.fk_ServiceID
    where inv.EntryDateTime between @FromDate and @ToDate
    group by cast(inv.EntryDateTime as date)
           , inv.InvoiceNo
           , b.BookingID
0 голосов
/ 04 июня 2018

Смешивание оконных функций и функций агрегирования может быть сложным.То, что вы хотите:

SUM(inv.ServicePrice) as TotalPrice,
SUM(SUM(inv.ServicePrice)) over () as TotalRevenue

Обратите внимание на дополнительные SUM().Внутренний - это SUM() в строке в наборе результатов.Внешняя - это оконная функция, которая суммирует значение по всем строкам.

...