如何使此累计销售查询跨越所有24小时

时间:2012-01-20 16:25:09

标签: sql sql-server-2008

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 个答案:

答案 0 :(得分:1)

通常,我建议您将设计更改为不需要此设计。但是,如果你真的需要它;创建要加入的模板,这些模板可确保您拥有所需的所有记录。

您可能预先填充了每天的日历表。也许一小时的桌子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,那么您可能会获得不错的整体性能。