我有一个查询,我建立的数据可以将净销售额YTD提高到最近完成的月份。查询联合会根据发票和贷项凭证汇总。它效果很好。我在另一个工具中使用查询,通过卡片码进行求和,并允许我执行有趣的操作等等。下面是该查询:按年份选择最高百分比
select x.cardcode,
x.customer,
case
when x.rep is null then (select slpname from ocrd inner join oslp on ocrd.slpcode = oslp.slpcode where ocrd.cardcode = x.cardcode)
else
x.rep
end as rep,
x.city,
x.state,
x.country,
case
when isnumeric(x.total) = 0 then 0
else x.total
end as [net total],
x.docdate
from (
select t0.cardcode as cardcode,
t0.[cardname] as customer,
t1.city as city,
t1.state as state,
t1.country as country,
t4.slpname as rep,
sum(t3.linetotal) - t2.discsum as total,
t2.docdate as [docdate]
from ocrd t0
inner join crd1 t1 on (t0.cardcode = t1.cardcode and t0.shiptodef = t1.address)
left outer join oinv t2 on t0.cardcode = t2.cardcode
left outer join inv1 t3 on t2.docentry = t3.docentry
left outer join oslp t4 on t2.slpcode = t4.slpcode
where t0.[cardtype] = 'C' and
t1.adrestype = 'S'
group by t0.cardcode, t0.cardname, t1.city, t1.state, t1.country, t4.slpname, t2.discsum, t2.docdate
union all
select t0.cardcode as cardcode,
t0.cardname as customer,
t1.city as city,
t1.state as state,
t1.country as country,
t4.slpname as rep,
-1*(sum(t3.linetotal) - t2.discsum) as total,
t2.docdate
from ocrd t0
inner join crd1 t1 on (t0.cardcode = t1.cardcode and t0.shiptodef = t1.address)
left outer join orin t2 on t0.cardcode = t2.cardcode
left outer join rin1 t3 on t2.docentry = t3.docentry
left outer join oslp t4 on t2.slpcode = t4.slpcode
where t0.[cardtype] = 'C' and
t1.adrestype = 'S'
group by t0.cardcode,
t0.cardname,
t1.city,
t1.state,
t1.country,
t4.slpname,
t2.discsum,
t2.docdate) x
where (x.docdate between '2008/01/01' and dateadd(day, -1, '2008/' + cast(month(getdate()) as varchar(2)) + '/01')
or x.docdate between '2009/01/01' and dateadd(day, -1, '2009/' + cast(month(getdate()) as varchar(2)) + '/01')
or x.docdate between '2010/01/01' and dateadd(day, -1, '2010/' + cast(month(getdate()) as varchar(2)) + '/01'))
group by x.cardcode, x.customer, x.rep, x.city, x.state, x.country, x.total, x.docdate
现在,我想修改查询返回的前n,说20,客户的总净值每年的百分比。这是我遇到麻烦的地方。我首先使用SQL Server,所以我想我会尝试使用row_number()结束(分区....但我没有得到它很正确(我知道它不正确,因为我可以检查它反对报告,我是反向工程。)这是我第一次尝试。
select m.Cardcode, m.Customer, m.Rep, m.City, m.State, m.Country, m.Nettotal as 'Net Total', m.docdate as 'Posting Date'
from (
select t.cardcode, t.customer, t.rep, t.city, t.state, t.country, t.nettotal, t.docdate, row_number() over(partition by t.docdate order by t.nettotal desc) as rownum
from (
select x.cardcode,
x.customer,
case
when x.rep is null then (select slpname from ocrd inner join oslp on ocrd.slpcode = oslp.slpcode where ocrd.cardcode = x.cardcode)
else
x.rep
end as rep,
x.city,
x.state,
x.country,
case
when isnumeric(x.total) = 0 then 0
else x.total
end as nettotal,
x.docdate
from (
select t0.cardcode as cardcode,
t0.[cardname] as customer,
t1.city as city,
t1.state as state,
t1.country as country,
t4.slpname as rep,
sum(t3.linetotal) - t2.discsum as total,
t2.docdate as docdate
from ocrd t0
inner join crd1 t1 on (t0.cardcode = t1.cardcode and t0.shiptodef = t1.address)
left outer join oinv t2 on t0.cardcode = t2.cardcode
left outer join inv1 t3 on t2.docentry = t3.docentry
left outer join oslp t4 on t2.slpcode = t4.slpcode
where t0.[cardtype] = 'C' and
t1.adrestype = 'S'
group by t0.cardcode,
t0.cardname,
t1.city,
t1.state,
t1.country,
t4.slpname,
t2.discsum,
t2.docdate
union all
select t0.cardcode as cardcode,
t0.cardname as customer,
t1.city as city,
t1.country as country,
t1.state as state,
t4.slpname as rep,
-1*(sum(t3.linetotal) - t2.discsum) as total,
t2.docdate
from ocrd t0
inner join crd1 t1 on (t0.cardcode = t1.cardcode and t0.shiptodef = t1.address)
left outer join orin t2 on t0.cardcode = t2.cardcode
left outer join rin1 t3 on t2.docentry = t3.docentry
left outer join oslp t4 on t2.slpcode = t4.slpcode
where t0.[cardtype] = 'C' and
t1.adrestype = 'S'
group by t0.cardcode,
t0.cardname,
t1.city,
t1.state,
t1.country,
t4.slpname,
t2.discsum,
t2.docdate) x
where (x.docdate between '2008/01/01' and dateadd(day, -1, '2008/' + cast(month(getdate()) as varchar(2)) + '/01')
or x.docdate between '2009/01/01' and dateadd(day, -1, '2009/' + cast(month(getdate()) as varchar(2)) + '/01')
or x.docdate between '2010/01/01' and dateadd(day, -1, '2010/' + cast(month(getdate()) as varchar(2)) + '/01'))
group by x.cardcode,
x.customer,
x.rep,
x.city,
x.state,
x.country,
x.total,
x.docdate) as t
) as m
where rownum <= 20
走这条路是麻烦的,即使我这样做是正确,因为它不会让我获得前百分之n,刚刚与前n
我还没有尝试使用交叉应用或子选择来实现我想要的结果。
有人可以帮助我解决这个问题吗?另外,它是如何写入的可能效率不高nd硬编码的日期范围选择不是一个好的解决方案。我想有很多要改进:)
您的帮助表示赞赏。
什么版本的SQL Server您使用的是?你可以使用2008年吗? – Gabe 2010-12-07 05:16:00