本人想要实现某产品的销量统计,算法如下: 前两天的销量比较:如果前天比昨天高,则标记为正1;低,则标记为负1; 若持平,则标记为0. 并且按销量由高到低排序。 求高手一条sql语句解决(多条也行)。 已知条件: 表名:goods, 商品名:goodsname,交易时间:goodstime,销量:saleamount. 其中,商品有20种,记录估计1000条。 说明:只求sql,不用考虑其他sql语句以外的问题。
解决方案 »
- 使用lov的文本框属性Miscellaneous-LOV For Validation 为True,输入值后会报错
- oracle 新手,有没有像SQLserver的图形操作界面
- 排序问题
- oracle pro*c 嵌套子句查询老是报错,请高手指教!
- 谁来解释下ORA-00100和ORA-01403,ORA-01422和ORA-02112
- oracle 存储过程复制表的主键、索引等
- 我去下载form builder,却始终不行,请高手帮忙
- 巨难问题!!
- Oracle 7.34与PowerBuilder6.5 请问哪有下?
- ORACLE cast函数 将日期转换为字符串问题
- 返回多行结果想用一行显示的问题
- cursor 是否可以作为参数传递
select goodsname,goodstime,saleamount from goods/* 模拟数据
a 2012-12-10 00:00:00.000 5
a 2012-12-10 00:00:00.000 4
a 2012-12-09 00:00:00.000 5
a 2012-12-09 00:00:00.000 3
b 2012-12-10 00:00:00.000 5
b 2012-12-10 00:00:00.000 4
b 2012-12-09 00:00:00.000 5
b 2012-12-09 00:00:00.000 4
c 2012-12-10 00:00:00.000 6
c 2012-12-10 00:00:00.000 4
c 2012-12-09 00:00:00.000 5
c 2012-12-09 00:00:00.000 3
d 2012-12-10 00:00:00.000 5
d 2012-12-10 00:00:00.000 4
e 2012-12-09 00:00:00.000 5
e 2012-12-09 00:00:00.000 3*/
-- 统计 goodsname 商品名称, Comparison 比较结果, mountYesterday 昨天销售量, mountBeforeYesterday 前天销售量select goodsname
,case when isnull(mountBeforeYesterday,0)> isnull(mountYesterday,0) then 1 when isnull(mountBeforeYesterday,0)< isnull(mountYesterday,0) then -1 else 0 end Comparison
,isnull(mountYesterday,0) mountYesterday,isnull(mountBeforeYesterday,0) mountBeforeYesterday
from
(select distinct goodsname from goods) t
left join (
select sum(a.saleamount) mountYesterday,a.goodsname gnYesterday
from goods a
where convert(varchar(10),a.goodstime,23) =convert(char(10), dateadd(day,-1,getdate()),23)
group by a.goodsname
) t1 on t1.gnYesterday=t.goodsname
left join (
select sum(b.saleamount) mountBeforeYesterday,b.goodsname gnBeforeYesterday
from goods b
where convert(varchar(10),b.goodstime,23) =convert(char(10), dateadd(day,-2,getdate()),23)
group by b.goodsname
) t2 on t2.gnBeforeYesterday=t.goodsname/* 统计结果a -1 9 8
b 0 9 9
c -1 10 8
d -1 9 0
e 1 0 8*/
--注意,测试数据 12月11日有效--查看模拟数据
select goodsname,goodstime,saleamount from goods
/* 模拟数据
a 2012-12-10 00:00:00.000 5
a 2012-12-10 00:00:00.000 4
a 2012-12-09 00:00:00.000 5
a 2012-12-09 00:00:00.000 3
b 2012-12-10 00:00:00.000 5
b 2012-12-10 00:00:00.000 4
b 2012-12-09 00:00:00.000 5
b 2012-12-09 00:00:00.000 4
c 2012-12-10 00:00:00.000 6
c 2012-12-10 00:00:00.000 4
c 2012-12-09 00:00:00.000 5
c 2012-12-09 00:00:00.000 3
d 2012-12-10 00:00:00.000 5
d 2012-12-10 00:00:00.000 4
e 2012-12-09 00:00:00.000 5
e 2012-12-09 00:00:00.000 3
*/
-- 统计 goodsname 商品名称, Comparison 比较结果, mountYesterday 昨天销售量, mountBeforeYesterday 前天销售量,total 销售量
select goodsname
,case when isnull(mountBeforeYesterday,0)> isnull(mountYesterday,0) then 1 when isnull(mountBeforeYesterday,0)< isnull(mountYesterday,0) then -1 else 0 end Comparison
,isnull(mountYesterday,0) mountYesterday,isnull(mountBeforeYesterday,0) mountBeforeYesterday
,total
from
(select goodsname,sum(saleamount) total from goods group by goodsname) t
left join (
select sum(a.saleamount) mountYesterday,a.goodsname gnYesterday
from goods a
where convert(varchar(10),a.goodstime,23) =convert(char(10), dateadd(day,-1,getdate()),23)
group by a.goodsname
) t1 on t1.gnYesterday=t.goodsname
left join (
select sum(b.saleamount) mountBeforeYesterday,b.goodsname gnBeforeYesterday
from goods b
where convert(varchar(10),b.goodstime,23) =convert(char(10), dateadd(day,-2,getdate()),23)
group by b.goodsname
) t2 on t2.gnBeforeYesterday=t.goodsname
order by t.total desc
/* 统计结果
b 0 9 9 18
c -1 10 8 18
a -1 9 8 17
d -1 9 0 9
e 1 0 8 8
*/
select * from goods;
1 a 20121201 9
2 a 20121202 11
3 a 20121203 8
4 a 20121204 7
5 a 20121205 7
6 a 20121206 9
7 a 20121207 17
8 a 20121208 9
9 a 20121209 21
为了看得清楚一些,我查询了几个冗余的字段select t1.goodname,
t1.goodtime,
t1.saleamount today,
t2.saleamount yesterday,
t1.saleamount - t2.saleamount "t1-t2",
sign(t1.saleamount - t2.saleamount) flag
from goods t1, goods t2
where t1.goodtime = t2.goodtime(+) + 1至于按降序排列,就不说了
select * from goods;
1 a 20121201 9
2 a 20121202 11
3 a 20121203 8
4 a 20121204 7
5 a 20121205 7
6 a 20121206 9
7 a 20121207 17
8 a 20121208 9
9 a 20121209 21
为了看得清楚一些,我查询了几个冗余的字段select t1.goodname,
t1.goodtime,
t1.saleamount today,
t2.saleamount yesterday,
t1.saleamount - t2.saleamount "t1-t2",
sign(t1.saleamount - t2.saleamount) flag
from goods t1, goods t2
where t1.goodtime = t2.goodtime(+) + 1结果如下所示:
GOODNAME GOODTIME TODAY YESTERDAY t1-t2 FLAG
a 20121201 9
a 20121202 11 9 2 1
a 20121203 8 11 -3 -1
a 20121204 7 8 -1 -1
a 20121205 7 7 0 0
a 20121206 9 7 2 1
a 20121207 17 9 8 1
a 20121208 9 17 -8 -1
a 20121209 21 9 12 1
goodsname,
sum(salemount) as salemount
from goods
where goodstime >= trunc(sysdate-2,'DD')
and goodstime < trunc(sysdate-1,'DD')
group by goodsname),
a2 as (select trunc(goodstime,'DD') as date_id, -- 昨天的销量
goodsname,
sum(salemount) as salemount
from goods
where goodstime >= trunc(sysdate-1,'DD')
and goodstime < trunc(sysdate,'DD')
group by goodsname),
a3 as (select nvl(a1.date_id,a2.date_id-1) as qt_date_id, -- 前天日期
nvl(a1.goodsname,a2.goodsname) as goodsname,-- 商品名
nvl(a1.salemount,0) as qt_salemount, -- 前天销量
nvl(a2.date_id,a1.date_id+1) as zt_date_id, -- 昨天日期
nvl(a2.salemount,0) as zt_salemount -- 昨天销量
from a1 full join a2 on a1.goodsname=a2.goodsname)
select a3.goodsname,
(case when a3.qt_salemount>a3.zt_salemount then 1 -- 如果前天比昨天高,则标记为1
when a3.qt_salemount<a3.zt_salemount then -1 -- 如果前天比昨天低,则标记为-1
else 0 -- 否则(销量一样)则标记为0
end) as sale_sign, -- 销售增幅
a3.qt_salemount+a3.zt_salemount as two_salemount -- 两天销量总和
from a3
order by a3.qt_salemount+a3.zt_salemount desc;-- 按 近两天各商品销量和 降序排序