sql偏题:排序,比较统计

sql难题:排序,比较统计本人想要实现某产品的销量统计,算法如下: 前两天的销量比较:如果前天比昨天高,则标

sql难题:排序,比较统计
本人想要实现某产品的销量统计,算法如下: 

前两天的销量比较:如果前天比昨天高,则标记为正1;低,则标记为负1; 

若持平,则标记为0. 并且按销量由高到低排序。 

求高手一条sql语句解决(多条也行)。 

已知条件: 

表名:goods, 商品名:goodsname,交易时间:goodstime,销量:saleamount. 

其中,商品有20种,记录估计1000条。 

说明:只求sql,不用考虑其他sql语句以外的问题。

[解决办法]
--查看模拟数据
select goodsname,goodstime,saleamount from goods

/* 模拟数据
a2012-12-10 00:00:00.0005
a2012-12-10 00:00:00.0004
a2012-12-09 00:00:00.0005
a2012-12-09 00:00:00.0003
b2012-12-10 00:00:00.0005
b2012-12-10 00:00:00.0004
b2012-12-09 00:00:00.0005
b2012-12-09 00:00:00.0004
c2012-12-10 00:00:00.0006
c2012-12-10 00:00:00.0004
c2012-12-09 00:00:00.0005
c2012-12-09 00:00:00.0003
d2012-12-10 00:00:00.0005
d2012-12-10 00:00:00.0004
e2012-12-09 00:00:00.0005
e2012-12-09 00:00:00.0003

*/
-- 统计 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-198
b099
c-1108
d-190
e108

*/
[解决办法]
--上个忘排序了,呵呵
--注意,测试数据 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
/* 统计结果
 
b09918
c-110818
a-19817
d-1909
e1088
 
*/ 
[解决办法]
sql偏题:排序,比较统计模拟数据
 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 GOODTIMETODAYYESTERDAYt1-t2FLAG
a 201212019
a 20121202119         21
a 20121203811         -3-1
a 2012120478         -1-1
a 2012120577         00
a 2012120697         21
a 20121207179         81
a 20121208917         -8-1
a 20121209219         121

[解决办法]
with a1 as (select trunc(goodstime,'DD') as date_id, -- 前天的销量
                   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;

-- 按 近两天各商品销量和 降序排序