首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 数据库 > SQL Server >

来了,来了, SQL 偏题, 求指点

2013-09-06 
来了,来了, SQL 难题, 求指点 。-------- 订单表 ----CREATE TABLE #tOrder(RefNum VARCHAR(20),--订单编号

来了,来了, SQL 难题, 求指点 。

-------- 订单表 ----
CREATE TABLE #tOrder
(
    RefNum VARCHAR(20),  --订单编号
    SKU VARCHAR(20),     --SKU 编号
    NUM INT              --SKU 数量
)

INSERT INTO #tOrder SELECT 'Ref001','EAY102(black)',20
INSERT INTO #tOrder SELECT 'Ref001','EAY102(blue)',10
INSERT INTO #tOrder SELECT 'Ref002','EAY102(black)',20
INSERT INTO #tOrder SELECT 'Ref003','EAY102(blue)',40
INSERT INTO #tOrder SELECT 'Ref004','EAY102(green)',40


----- SKU 流水号信息 ----
CREATE TABLE #tmp
(
   ImportID INT,           ----关联#FlowInfo 表 ImportID
   SKU VARCHAR(20),        ----SKU 编号
   FlowNo_From VARCHAR(10),----流水号起始
   FLowNo_To VARCHAR(10),  ----流水号截止
   Location VARCHAR(10)    ----货架号 
)

INSERT INTO #tmp SELECT 13,'EAY102(black)','0061','0100','D127'
INSERT INTO #tmp SELECT 13,'EAY102(black)','0031','0060','D126'
INSERT INTO #tmp SELECT 13,'EAY102(black)','0001','0030','D125'
INSERT INTO #tmp SELECT 14,'EAY102(blue)','0001','0100','D124'
INSERT INTO #tmp SELECT 15,'EAY102(green)','0051','0090','D123'
INSERT INTO #tmp SELECT 15,'EAY102(green)','0001','0050','D122'

------- 流水号记录表 ---
CREATE TABLE #FlowInfo
(
   ImportID INT,        --- ID
   FlowNo VARCHAR(10),--- 流水号
   Ttype INT            --- 0 坏品, 1 已出库
)

INSERT INTO #FlowInfo SELECT 13,'0098',0
INSERT INTO #FlowInfo SELECT 15,'0010',0
INSERT INTO #FlowInfo SELECT 15,'0012',0


SELECT * FROM #tOrder
SELECT * FROM #tmp
SELECT * FROM #FlowInfo



--------------- 最终效果(执行查看), --------------
SELECT 'Ref001' AS RefNum,'EAY102(black)' AS SKU,'0099-0100' AS FlowNo,2 AS Num,'D127' AS Location
UNION ALL
SELECT 'Ref001','EAY102(black)','0080-0097',18,'D127'
UNION ALL


SELECT 'Ref001','EAY102(blue)','0091-0100',10,'D124'
UNION ALL
SELECT 'Ref002','EAY102(black)','0061-0079',19,'D127'
UNION ALL
SELECT 'Ref002','EAY102(black)','0060-0060',1,'D126'
UNION ALL
SELECT 'Ref003','EAY102(blue)','0051-0090',40,'D124'
UNION ALL
SELECT 'Ref004','EAY102(green)','0051-0090',40,'D123'



------ 下面说下,这结果是怎么来的 
------ 按每个订单,记录所出的SKU所对应的流水号以及货架号(Location) ,流水号从大往小获取
------ 如果流水号范围内有坏品 (#tmp 表ImportID 关联 #FlowInfo 表,Ttype=0),则不记录坏评的流水号
------ 比如 #FlowInfo 表中ImportID=13 有个 流水号:0098 是坏品,所以最后结果 0099-0100 , 0080-0097 显示
-------RefNumSKUFlowNoNumLocation
-------Ref001EAY102(black)0099-01002D127
-------Ref001EAY102(black)0080-009718D127

drop table #tmp
drop table #FlowInfo
drop table #tOrder


[解决办法]

-------- 订单表 ----
CREATE TABLE #tOrder
(
    RefNum VARCHAR(20),  --订单编号
    SKU VARCHAR(20),     --SKU 编号
    NUM INT              --SKU 数量
)

INSERT INTO #tOrder SELECT 'Ref001','EAY102(black)',20
INSERT INTO #tOrder SELECT 'Ref001','EAY102(blue)',10
INSERT INTO #tOrder SELECT 'Ref002','EAY102(black)',20
INSERT INTO #tOrder SELECT 'Ref003','EAY102(blue)',40
INSERT INTO #tOrder SELECT 'Ref004','EAY102(green)',40


----- SKU 流水号信息 ----
CREATE TABLE #tmp
(
   ImportID INT,           ----关联#FlowInfo 表 ImportID
   SKU VARCHAR(20),        ----SKU 编号
   FlowNo_From VARCHAR(10),----流水号起始
   FLowNo_To VARCHAR(10),  ----流水号截止
   Location VARCHAR(10)    ----货架号 
)

INSERT INTO #tmp SELECT 13,'EAY102(black)','0061','0100','D127'


INSERT INTO #tmp SELECT 13,'EAY102(black)','0031','0060','D126'
INSERT INTO #tmp SELECT 13,'EAY102(black)','0001','0030','D125'
INSERT INTO #tmp SELECT 14,'EAY102(blue)','0001','0100','D124'
INSERT INTO #tmp SELECT 15,'EAY102(green)','0051','0090','D123'
INSERT INTO #tmp SELECT 15,'EAY102(green)','0001','0050','D122'

------- 流水号记录表 ---
CREATE TABLE #FlowInfo
(
   ImportID INT,        --- ID
   FlowNo VARCHAR(10),--- 流水号
   Ttype INT            --- 0 坏品, 1 已出库
)

INSERT INTO #FlowInfo SELECT 13,'0098',0
INSERT INTO #FlowInfo SELECT 15,'0010',0
INSERT INTO #FlowInfo SELECT 15,'0012',0


SELECT * FROM #tOrder
SELECT * FROM #tmp
SELECT * FROM #FlowInfo

------ 下面说下,这结果是怎么来的 
------ 按每个订单,记录所出的SKU所对应的流水号以及货架号(Location) ,流水号从大往小获取
------ 如果流水号范围内有坏品 (#tmp 表ImportID 关联 #FlowInfo 表,Ttype=0),则不记录坏评的流水号
------ 比如 #FlowInfo 表中ImportID=13 有个 流水号:0098 是坏品,所以最后结果 0099-0100 , 0080-0097 显示
-------RefNumSKUFlowNoNumLocation
-------Ref001EAY102(black)0099-01002D127
-------Ref001EAY102(black)0080-009718D127

if(OBJECT_ID('tempdb..#goodSKU') is not null)
drop table tempdb..#goodSKU;

select number,t.*
into #goodSKU
from master.dbo.spt_values sp
join #tmp t
on sp.number between t.FlowNo_From and t.FLowNo_To and [type]='p'
left join #FlowInfo f
on t.ImportID=f.ImportID and sp.number=f.FlowNo and f.Ttype=0
where f.FlowNo is null

if(OBJECT_ID('tempdb..#result') is not null)
drop table tempdb..#result;
create table #result
(RefNum varchar(50),SKU varchar(50),FlowNo varchar(50),Num int,Location varchar(50))

declare skuCursor Cursor for
select RefNum,SKU,NUM from #tOrder

open skuCursor
declare @RefNum varchar(50);
declare @SKU varchar(50);
declare @NUM int;

fetch next from skuCursor into @RefNum,@SKU,@NUM;
while @@FETCH_STATUS=0
begin

insert into #result
select @RefNum,@SKU,'00'+convert(varchar(20),MIN(number))+'-'+'00'+convert(varchar(20),MAX(number))FLowNo


,MAX(number)-MIN(number)+1 as num,Location
from
(
select number,SKU,Location,FlowNo_From,FlowNo_To,ROW_NUMBER() over(order by number desc) rn
,ROW_NUMBER() over(order by number ) rn2
from #goodSKU
where SKU=@SKU 
)t
where rn<=@NUM
group by Location,number-rn2;

delete  
from #goodSKU 
where SKU=@SKU 
and number in
(
select number
from
(
select number,SKU,Location,ROW_NUMBER() over(order by number desc) rn
from #goodSKU
where SKU=@SKU 
)t
where rn<=@NUM
)


fetch next from skuCursor into @RefNum,@SKU,@NUM
end

close skuCursor;
deallocate skuCursor;


select *
from #Result


--drop table #tmp
--drop table #FlowInfo
--drop table #tOrder
--drop table #Result


[解决办法]

;with t as(
select  a.importid,a.sku,a.location,b.number,row_number()over(partition by sku order by location desc,b.number desc) as ord from #tmp a inner join master..spt_values b
on convert(int,a.FlowNo_From)<=b.number
and convert(int,a.FlowNo_to)>=b.number 
where b.type='P'
and b.number>0
and not exists(select 1 from #FlowInfo c
where convert(int,c.FlowNo)=b.number
and a.importid=c.importid
and c.Ttype=0)),
t1 as
(select a.refnum,sku,a.num,row_number()over(partition by sku order by sku,refnum asc) as ord from #tOrder a inner join master..spt_values b
on a.num>=b.number
where b.type='P'
and b.number>0)
select t1.refnum,t1.sku,t.location,min(t.number),max(t.number),count(1) from t right join t1
on t.sku=t1.sku
and t1.ord=t.ord
group by t1.refnum,t1.sku,t.location,refnum+convert(nvarchar,t.number+t.ord)
order by t1.refnum,t1.sku,t.location

热点排行