2010-07-27 97 views
2

我有一個SQL Server CE 3.5表(交易)與下面的模式:幫我看看這個SQL查詢

  • ID
  • TRANSACTION_DATE
  • 類別
  • 說明
  • 金額

Q uery:

SELECT Transaction_Date, SUM(Amount) 
    FROM Transactions 
GROUP BY Transaction_Date; 

我試圖做一個SUM(金額)和GROUP BY TRANSACTION_DATE只是這樣我就可以得到每一天的總量,但我想回去值甚至好幾天沒有交易等等基本上沒有交易的一天的記錄只有$ 0.00的金額。

感謝您的幫助!

+0

SQL Server CE是否支持'master.dbo.spt_values'? – 2010-07-27 00:43:53

回答

0

您需要一個日曆表來選擇日期。或者,如果您有一個Numbers表格,則可以將其有效轉換爲日曆表格。基本上,它只是一個包含每個日期的表格。爲它構建和生成數據非常簡單,它適用於這些情況。然後,你會簡單地使用:

SELECT 
    C.calendar_date, 
    SUM(T.amount) 
FROM 
    Calendar C 
LEFT OUTER JOIN Transactions T ON 
    T.transaction_date = C.calendar_date 
GROUP BY 
    C.calendar_date 
ORDER BY 
    C.calendar_date 

有幾件事情要記住:

如果你發送這前端或報表引擎,那麼你應該只發送您的日期(您的原始查詢),並且如果可能的話,前端將自行填寫$ 0.00天。

另外,我在這裏假定日期是一個沒有時間分量的確切日期值(因此連接中的「=」)。您的日曆表可能包含「start_time」和「end_time」,以便您可以使用BETWEEN處理包含時間部分的日期。這樣可以節省您不必剝離時間部分並可能損壞索引使用情況。您也可以計算當天使用它的開始點和結束點,但由於它是預填充工作表,因此IMO更容易包含start_time和end_time。

-1

如果你想沒有交易出現 你可以每天增加一個僞交易爲零 它不會干擾SUM量,將讓你想

+0

我會非常強烈地暗示這一點。一旦你開始把垃圾放到你的數據庫中,這就是你最終擺脫它的原因。這種混合物總會有意想不到的後果。 – 2010-07-27 02:12:54

0

沒有什麼日期知道任何這一點也適用CE

隨着公共表表達式

DECLARE @StartDate DATETIME 
DECLARE @EndDate DATETIME 

SET @StartDate = '2010-07-10' 
SET @EndDate = '2010-07-20' 

;WITH Dates AS (
    SELECT @StartDate AS DateValue 
    UNION ALL 
    SELECT DateValue + 1 
    FROM Dates 
    WHERE DateValue + 1 <= @EndDate 
) 
SELECT  Dates.DateValue, ISNULL(SUM(Transactions.Amount), 0) 
FROM  Dates 
LEFT JOIN Transactions ON 
       Dates.DateValue = Transactions.Transaction_Date 
GROUP BY Dates.DateValue; 

隨着環+臨時表

DECLARE @StartDate DATETIME 
DECLARE @EndDate DATETIME 

SET @StartDate = '2010-07-10' 
SET @EndDate = '2010-07-20' 

SELECT @StartDate AS DateValue INTO #Dates 

WHILE @StartDate <= @EndDate 
BEGIN 
    SET @StartDate = @StartDate + 1 
    INSERT INTO #Dates VALUES (@StartDate) 
END 

SELECT  Dates.DateValue, ISNULL(SUM(Transactions.Amount), 0) 
FROM  #Dates AS Dates 
LEFT JOIN Transactions ON 
       Dates.DateValue = Transactions.Transaction_Date 
GROUP BY Dates.DateValue; 

DROP TABLE #Dates 
0

您需要以某種方式上下聲明您的聲明,但也許這會有所幫助。

DECLARE @Start smalldatetime, @End smalldatetime 

SELECT @Start = 'Jan 1 2010', @End = 'Jan 18 2010'; 

--- make a CTE of range of dates we're interested in 
WITH Cal AS (
    SELECT CalDate = convert(datetime, @Start) 
    UNION ALL 
    SELECT CalDate = dateadd(d,1,convert(datetime, CalDate)) FROM Cal WHERE CalDate < @End 

) 

SELECT CalDate AS TransactionDate, ISNULL(SUM(Amount),0) AS TransactionAmount 
FROM Cal AS C 
LEFT JOIN Transactions AS T On C.CalDate = T.Transaction_Date 
GROUP BY CalDate ; 
+0

我不認爲CTE在SQL Server CE中可用。 – 2010-07-27 02:17:29

0

一旦你有一個日曆表(稍後更多),那麼你可以做你的數據來填充缺少的日期範圍內加入:

SELECT CalendarDate, NULLIF(SUM(t.Amount),0) 
FROM (SELECT CalendardDate FROM Calendar 
WHERE CalendarDate>= (SELECT MIN(TransactionDate) FROM Transactions) AND 
    CalendarDate<= (SELECT MAX(TransactionDate) FROM Transactions)) c 
LEFT JOIN 
    Transactions t ON t.TransactionDate=c.CalendarDate 
GROUP BY CalendarDate 

創建日曆表,你可以使用一個CTE:

WITH CalendarTable 
AS 
(
    SELECT CAST('20090601' as datetime) AS [date] 
    UNION ALL 
    SELECT DATEADD(dd, 1, [date]) 
    FROM CTE_DatesTable 
    WHERE DATEADD(dd, 1, [date]) <= '20090630' /* last date */ 
) 
SELECT [date] FROM CTE_DatesTable 
OPTION (MAXRECURSION 0); 

結合這兩個,我們有

WITH CalendarTable 
AS 
(
    SELECT MIN(TransactionDate) FROM Transactions AS [date] 
    UNION ALL 
    SELECT DATEADD(dd, 1, [date]) 
    FROM CTE_DatesTable 
    WHERE DATEADD(dd, 1, [date]) <= (SELECT MAX(TransactionDate) FROM Transactions) 
) 
SELECT c.[date], NULLIF(SUM(t.Amount),0) 
FROM Calendar c 
LEFT JOIN 
    Transactions t ON t.TransactionDate=c.[date] 
GROUP BY c.[date]