我有下表。
DATE | AMT
10/10 | 300
12/10 | 300
01/11 | 200
03/11 | 100
如何获得每月总数?结果如 -
DATE | TOT
1010 | 300
1110 | 300
1210 | 600
0111 | 800
0211 | 800
0311 | 900
像
这样的sql语句SELECT SUM(AMT) FROM TABLE1 WHERE DATE BETWEEN '1010' AND '0111'
会导致800为0111,但......
注意没有日期限制。这是我的困境。如何在不对所有日期执行循环的情况下填充此列并显示缺少的月份?
答案 0 :(得分:2)
为了迎合缺失的月份,请创建一个加入的模板表。
将其视为缓存。而不是循环填补空白,只需在数据库中缓存日历。
您甚至可以将多个日历(月初,周开始,银行假日,工作日等)全部合并到一个表中,并附带一堆搜索标记和索引。
你最终得到像......
SELECT
calendar.date,
SUM(data.amt)
FROM
calendar
LEFT JOIN
data
ON data.date >= calendar.date
AND data.date < calendar.date + INTERVAL 1 MONTH
WHERE
calendar.date >= '20110101'
AND calendar.date < '20120101'
GROUP BY
calendar.date
修改强>
我刚注意到OP需要一个总计。
这在SQL中是可能的,但它非常效率低下。原因是一个月的结果不用于计算下个月。相反,必须再次计算整个运行总量。
出于这个原因,通常强烈建议您按上述方法计算月度总数,然后使用您的应用程序进行迭代并计算运行总值。
如果真的必须在SQL中执行,那就像......
SELECT
calendar.date,
SUM(data.amt)
FROM
calendar
LEFT JOIN
data
ON data.date >= @yourFirstDate
AND data.date < calendar.date + INTERVAL 1 MONTH
WHERE
calendar.date >= @yourFirstDate
AND calendar.date < @yourLastDate
GROUP BY
calendar.date
答案 1 :(得分:0)
主要问题是and have the missing months displayed as well?
我没有看到如何使用包含要显示的月\年组合的辅助表来执行此操作:
create table table1(
date datetime,
amt int
)
insert into table1 values ('10/10/2010',100)
insert into table1 values ('12/12/2010',200)
insert into table1 values ('01/01/2011',50)
insert into table1 values ('03/03/2011',500)
truncate table #dates
create table #dates(
_month int,
_year int
)
insert into #dates values(10,2010)
insert into #dates values(11,2010) --missing month
insert into #dates values(12,2010)
insert into #dates values(01,2011)
insert into #dates values(02,2011)--missing month
insert into #dates values(03,2011)
select D._month, D._year, sum(amt)
from #dates D left join TABLE1 T on D._month=month(T.date) and D._year=year(T.date)
group by D._month, D._year
答案 2 :(得分:0)
您还可以动态生成范围,将其值作为间隔传递给DATE_ADD,并基本上投射一系列月份值。
正如@Dems所说,你需要有一个相关的子查询来计算运行总数,这将是非常低效的,因为它将在内部运行一个嵌套循环。
要了解如何生成序列,请在此处查看我的帖子: How to generate a range of numbers in Mysql
结束查询应该如下所示:(顺便说一下,你应该有一个日期列,而不是这个varchar混乱)。
/*NOTE: This assumes a derived table (inline view) containing the sequence of date values and their corresponding TOT value*/
SELECT
DATEVALUES.DateValue,
(
SELECT SUM(TABLE1.AMT) FROM TABLE1 WHERE TABLE1.DateValue <= DATEVALUES.DateValue)
) AS RunningSubTotal
FROM
DATEVALUES
或类似的东西。
答案 3 :(得分:-2)
select sum(AMT) from TABLE1 group by Date