Как сделать, чтобы этот кумулятивный запрос на продажу охватывал все 24 часа - PullRequest
1 голос
/ 20 января 2012

vwSalesByHour работает, как и ожидалось, показывая только записи за часы, в которые были продажи. Естественно, vwCumulativeDaySalesByHour также показывает только записи по часам, в течение которых были продажи, но мне нужно, чтобы показывать запись по каждому часу дня. Я знаю, что должен быть простой способ сделать это проще, чем то, о чем я думал до сих пор ... если бы кто-то был так любезен, чтобы указать мне на это:)

--This works great
CREATE VIEW vwSalesByHour AS

select      SUM(t.TranAmount - t.DeliveryFee - t.TaxAmount) Sales, 
            BusinessDate,
            DATEPART(HH, OrderTime) Hour
from        transactions t
where       TranState <> 11 and TicketNumber > 0
group by    BusinessDate, DATEPART(HH, OrderTime)


--But I would like this to return records for all 24 hours
CREATE VIEW vwCumulativeDaySalesByHour
AS
select  min(s1.Sales) Sales, 
        sum(s2.Sales) CumulativeSales, 
        s1.BusinessDate, s1.Hour

from    SalesByHour s1 join 
        SalesByHour s2 on s1.BusinessDate = s2.BusinessDate and
                          s1.Hour >= s2.Hour
group by s1.BusinessDate, s1.Hour

1 Ответ

1 голос
/ 20 января 2012

Как правило, я рекомендую изменить ваш дизайн, чтобы не требовать этого. Но если вам это действительно нужно; Создавайте шаблоны для присоединения, это гарантирует, что у вас есть все нужные записи.

Возможно, у вас есть таблица календаря, в которой каждый день предварительно заполнен. И, может быть, почасовой стол с 24 часами заселения. Или одна таблица, составляющая все, что вам может понадобиться (год, месяц, неделя, день, час, интервал и т. Д. В виде различных столбцов, а затем с несколькими индексами покрытия) .

Даже в крайних случаях это обычно не занимает много места, и существенно упрощает запросы и (обычно) экономит значительное время обработки.

Затем вы получите что-то вроде этого ...

SELECT
  calendar.date,
  hours.hour,
  SUM(SalesByHour.Sales)                                                        AS CumulativeSales,
  MAX(CASE WHEN SalesByHour.Hour = hours.hour THEN Sales.Sales ELSE NULL END)   AS Sales
FROM
  calendar
CROSS JOIN
  hours
LEFT JOIN
  SalesByHour
    ON  SalesByHour.BusinessDate = calendar.date
    AND SalesByHour.Hour        <= hours.hour
GROUP BY
  calendar.date,
  hours.hour

Альтернатива - просто заполнить пробелы в вашем клиенте. Но это моё распределение определенной логики по клиенту и SQL. Точный лучший способ избежать этой потребности зависит от ситуации. Но я рекомендую найти способ не нуждаться в этом, если это все возможно.

То же самое относится и к совокупным значениям. Общеизвестно, что SQL плохо работает с такими суммами. Если клиент может обработать промежуточный итог вместо SQL, вы, вероятно, получите приличное общее снижение производительности.

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