我有一张产品库存表(ProductStockTemp
):
ProductStockId | ProductCode | ProductName | ProductStockClosingBalance
-------------------------------------------------------------------------
1 | A1 | A2 | 200
2 | B1 | B2 | 0
3 | A1 | A2 | 100
4 | C1 | C2 | -400
5 | B1 | B2 | 700
6 | C1 | C2 | 0
7 | D1 | D2 | 0
8 | D1 | D2 | 0
我想创建一个像这样的表
ProductCode | ProductName | TypeA | TypeB
------------------------------------------
A1 | A2 | 200 | 100
B1 | B2 | 0 | 700
C1 | C2 | -400 | 0
D1 | D2 | 0 | 0
这意味着第一个产品记录将是产品类型A,最新记录将是产品类型B.我认为我必须首先选择最新的产品记录。但是,当产品出现一次然后它将选择此记录时出现问题。在这种情况下,我希望产品类型B为0,因为第一个将是产品类型A,最新的将是类型B.我的查询选择表中的最新产品记录
select
p.ProductCode,
p.ProductName,
p.ProductStockClosingBalance
from
ProductStockTemp p
where
p.ProductStockId = (select MAX(q.ProductStockId)
from ProductStockTemp q
where p.ProductCode = q.ProductCode)
order by
p.ProductCode
我现在真的被困住了!
答案 0 :(得分:0)
使用以下查询
;With ctef as (select ProductCode , ProductName , ProductStockClosingBalance
row_number()over(partition by ProductCode , ProductName ordered by ProductStockId asc) as r from ProductStock)
, ctef1 as ( select * from ctef where r =1)
, ctel as (select ProductCode , ProductName , ProductStockClosingBalance
row_number()over(partition by ProductCode , ProductName ordered by ProductStockId desc)as r2 from ProductStock )
, ctel1 as ( select * from ctel where r =1)
select f.ProductCode , f.ProductName ,f.ProductStockClosingBalance as typea ,nullif(l.ProductStockClosingBalance ,f.ProductStockClosingBalance ) as typeB
from ctef1 f left join ctel1 s
on f.ProductCode =s.ProductCode and f.ProductName =s.ProductName
如果使用sql servere 2012或更高版本,可以使用分析函数FIRST_VALUE (Transact-SQL)和LAST_VALUE (Transact-SQL)。
答案 1 :(得分:0)
我建议你学习SQL GROUP BY语句
SELECT ProductCode, ProductName, min(ProductStockClosingBalance) as TypeA, Max(ProductStockClosingBalance) as TypeB
FROM ProductStockTemp p
GROUP BY ProductCode, ProductName
答案 2 :(得分:0)
对于这个案子,我认为最为明显的是:
;with cteStock as
(
select
p.ProductCode,
p.ProductName,
p.ProductStockClosingBalance,
row_number() over(partition by p.ProductCode, p.ProductName order by p.ProductStockId asc) rn_asc,
row_number() over(partition by p.ProductCode, p.ProductName order by p.ProductStockId desc) rn_desc,
from ProductStockTemp p
)
select
s.ProductCode, s.ProductName,
sum(case when s.rn_asc = 1 then s.ProductStockClosingBalance else 0) as TypeA,
sum(case when s.rn_desc = 1 and s.rn_asc != s.rn_desc then s.ProductStockClosingBalance else 0) as TypeB
from cteStock s
group by s.ProductCode, s.ProductName
但是这样一个非规范化的表没有任何好处,没有关于句号和名称的信息存储在这里。
s.rn_asc != s.rn_desc
- 对于只有一行的情况。
不确定默认零,但它取决于您和您的任务定义。
答案 3 :(得分:0)
此查询可以满足您的需求。
declare @prod table(ProductStockId int, ProductCode varchar(10), ProductName varchar(10), ProductStockClosingBalance int)
insert @prod values
( 1 , 'A1' , 'A2' , 200),
( 2 , 'B1' , 'B2' , 0),
( 3 , 'A1' , 'A2' , 100),
( 4 , 'C1' , 'C2' , -400),
( 5 , 'B1' , 'B2' , 700),
( 6 , 'C1' , 'C2' , 0),
( 7 , 'D1' , 'D2' , 0),
( 8 , 'D1' , 'D2' , 0 )
;with prod as(
select *
,ROW_NUMBER() over(partition by productcode order by ProductStockId) rn1
,ROW_NUMBER() over(partition by productcode order by ProductStockId desc) rn2
from @prod
)
select productcode,ProductName,
(select ProductStockClosingBalance from prod p1 where p.productcode=p1.ProductCode and p1.rn1=1) TypeA,
ProductStockClosingBalance typeB
from prod p
where rn2=1
结果:
productcode ProductName TypeA typeB
A1 A2 200 100
B1 B2 0 700
C1 C2 -400 0
D1 D2 0 0