创建摘要表SQL

时间:2016-06-09 04:23:42

标签: sql-server

我有一张产品库存表(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

我现在真的被困住了!

4 个答案:

答案 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