我的表记录如下
ym cnt
200901 57
200902 62
200903 67
...
201001 84
201002 75
201003 75
...
201101 79
201102 77
201103 80
...
我想计算当月和每月之间的差异。 结果如下......
ym cnt diff
200901 57 57
200902 62 5 (62 - 57)
200903 67 5 (67 - 62)
...
201001 84 ...
201002 75
201003 75
...
201101 79
201102 77
201103 80
...
有谁能告诉我如何编写一个sql来获得结果并获得良好的性能?
更新
抱歉简单的话
我的解决方案是
step1: input the currentmonth data into temp table1
step2: input the permonth data into temp table2
step3: left join 2 tables to compute the result
Temp_Table1
SELECT (ym - 1) as ym , COUNT( item_cnt ) as cnt
FROM _table
GROUP BY (ym - 1 )
order by ym
Temp_Table2
SELECT ym , COUNT( item_cnt ) as cnt
FROM _table
GROUP BY ym
order by ym
select ym , (b.cnt - a.cnt) as diff from Temp_Table2 a
left join Temp_Table1 b
on a.ym = b.ym
* 如果我想比较今年和去年的月份差异 我只能将ym - 1更改为ym - 100 *
但实际上,按键分组不仅仅是ym
最多有15个密钥和最多1亿条记录
所以,我想知道一个好的解决方案可以轻松管理来源
并且表现良好。
答案 0 :(得分:1)
对于MSSQL,它有一个对表的引用,因此它可能比左连接更快(可能不是),它有两个对表的引用:
-- ================
-- sample data
-- ================
declare @t table
(
ym varchar(6),
cnt int
)
insert into @t values ('200901', 57)
insert into @t values ('200902', 62)
insert into @t values ('200903', 67)
insert into @t values ('201001', 84)
insert into @t values ('201002', 75)
insert into @t values ('201003', 75)
-- ===========================
-- solution
-- ===========================
select
ym2,
diff = case when cnt1 is null then cnt2
when cnt2 is null then cnt1
else cnt2 - cnt1
end
from
(
select
ym1 = max(case when k = 2 then ym end),
cnt1 = max(case when k = 2 then cnt end),
ym2 = max(case when k = 1 then ym end),
cnt2 = max(case when k = 1 then cnt end)
from
(
select
*,
rn = row_number() over(order by ym)
from @t
) t1
cross join
(
select k = 1 union all select k = 2
) t2
group by rn + k
) t
where ym2 is not null
答案 1 :(得分:0)
有谁能告诉我如何编写一个sql来获得结果
绝对。只需获取具有下一个最高日期的行,然后减去。
并且表现良好?
没有。关系数据库实际上并不是线性遍历,即使使用索引也需要虚拟线性遍历。