2012-01-20 26 views
1

vwSalesByHour按預期工作,只顯示有銷售時間的記錄。自然,vwCumulativeDaySalesByHour也只顯示有銷售時間的記錄,但我需要它顯示一天中每個小時的記錄。我知道必須有一個簡單的方法來做到這一點比我所想的那麼容易得多......如果有人只是這麼好心指出來給我:)如何使此累積銷售查詢全部24小時

--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

一般來說,我建議改變你的設計,不要求這樣做。但是,如果你真的需要它,創建要加入的模板,這些可確保您擁有所需的每條記錄。

您可能有一個日曆表,每天都預先填充。也許是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,那麼可能會節省體面的整體性能。

+0

謝謝。這幾乎正​​是我想到的,但只是需要一些確認,我沒有忽略一些更簡單的方法。 –

+0

對於性能,它在一秒鐘左右的時間內運行了數年的數據,而且我只需要它在一天或最多一週內工作一次,所以我認爲我在那裏可以。但是這裏有一個額外的問題:如果在某個時候我想修改這個在24小時內沒有開始並且在午夜結束的時期,我想知道最簡單的方法是什麼? –

+1

組合的表格方法。也許三個字段'(Date,Hour,DateTime)',那麼你只需要'WHERE DateTime BETWEEN x AND y'。通過添加'Year,Month,Week'等來進一步擴大使用範圍,然後添加'IsStartOfYear,IsStartOfMonth,IsStartOfWeek,IsStartOfDay,IsStartOfHour'等字段。它可以增長到各種使用狀態。字段越多,索引越多,空間越多。你可能有多個表並加入它們。沒有選擇的結束。 – MatBailie