我有一个带有以下架构的SQL Server CE 3.5表(交易):
查询:
SELECT Transaction_Date, SUM(Amount)
FROM Transactions
GROUP BY Transaction_Date;
我正在尝试通过transaction_date执行SUM(金额)和分组,这样我就可以获得每天的总金额但是我想要获取值甚至几天没有交易所以基本上是一天的记录没有交易只需要0.00美元的金额。
感谢您的帮助!
答案 0 :(得分:0)
您需要一个日历表来选择日期。或者,如果您有Numbers表,则可以将其有效地转换为Calendar表。基本上,它只是一个包含每个日期的表格。它很容易为它构建和生成数据,并且在这些情况下非常方便。然后你只需使用:
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 :(得分: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
答案 2 :(得分: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 ;
答案 3 :(得分: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]
答案 4 :(得分:-1)
如果您希望显示没有交易的日期 您可以为每天添加DUMMY交易,金额为零 它不会干扰SUM,你会想要什么