添加带计算的汇总列

时间:2016-03-02 10:21:59

标签: sql sql-server summarization

我需要显示发票每行的序列号。这意味着,在一个位置上可以有几个序列号。除了序列号,还需要一个数量,这显然是一个数量。不幸的是,可能存在包含比序列号更多的项目的行。如果在装运过程中未扫描序列号,则会发生这种情况。在我的输出中,我需要为这些位置增加一行,其中显示REMAINING项目的数量。因此,假设有一个包含10个项目的位置,在运输过程中只扫描了4个。这意味着我打印四行,其中序列号和数量为一行,而第五行没有序列号,数量为六行。

我使用SQL Server 2008,并且更喜欢没有临时表或CTE的解决方案。

这是我的意思的一个例子:

CREATE TABLE #data (doc int, pos int, qty int)
CREATE TABLE #serial (doc int, pos int, serial varchar(10))

INSERT INTO #data
SELECT 1,1,6
UNION ALL
SELECT 1,2,3
UNION ALL
SELECT 2,1,4

INSERT INTO #serial
select 1,1,'aaaaaaaaaa'
UNION ALL
select 1,1,'bbbbbbbbbb'
UNION ALL
select 1,1,'cccccccccc'
UNION ALL
select 1,1,'dddddddddd'
UNION ALL
select 1,2,'eeeeeeeeee'
UNION ALL
select 1,2,'ffffffffff'
UNION ALL
select 1,2,'gggggggggg'
UNION ALL
select 2,1,'hhhhhhhhhh'

SELECT d.doc, d.pos, s.serial, CASE WHEN s.serial IS NOT NULL THEN 1 ELSE d.qty END qty
FROM #data d
INNER JOIN #serial s ON s.doc = d.doc and s.pos = d.pos

这是所需的输出:

doc | pos | serial     | qty
1   | 1   |'aaaaaaaaaa'| 1
1   | 1   |'bbbbbbbbbb'| 1
1   | 1   |'cccccccccc'| 1
1   | 1   |'dddddddddd'| 1
1   | 1   | NULL       | 2
1   | 2   |'eeeeeeeeee'| 1
1   | 2   |'ffffffffff'| 1
1   | 2   |'gggggggggg'| 1
2   | 1   |'hhhhhhhhhh'| 1
2   | 1   | NULL       | 3

3 个答案:

答案 0 :(得分:1)

select
  s.doc, s.pos, s.serial, d.qty - s.cnt qty
from
  (  select
    s.doc, s.pos, s.serial, count(*) cnt,
    case when grouping(s.doc) = 0 and grouping(s.pos) = 0 and grouping(s.serial) = 1 then 1 else 0 end grp
  from
    #serial s
  group by
    s.doc, s.pos, s.serial with cube
  having
    grouping(s.doc) = 0 and grouping(s.pos) = 0 and grouping(s.serial) = 1
    or grouping(s.doc) = 0 and grouping(s.pos) = 0 and grouping(s.serial) = 0
    ) s
  left join #data d on s.doc = d.doc and s.pos = d.pos and s.grp = 1
where
  s.grp = 0 or d.qty - s.cnt > 0
order by
  s.doc, s.pos, s.grp

答案 1 :(得分:0)

Are you looking for this ..?

SELECT d.doc, d.pos, s.serial, CASE WHEN s.serial IS NOT NULL THEN 1 ELSE d.qty END qty
FROM @data d
INNER JOIN @serial s ON s.doc = d.doc AND s.pos = d.pos

UNION ALL

SELECT d.doc, d.pos, NULL serial, d.qty - s.qty
FROM @data d
INNER JOIN (
    SELECT doc, pos, count(*) AS qty
    FROM @serial
    GROUP BY doc, pos
    ) s ON s.doc = d.doc AND s.pos = d.pos
WHERE d.qty - s.qty <> 0
ORDER BY doc, pos

Output

doc pos serial  qty
1   1   aaaaaaaaaa  1
1   1   bbbbbbbbbb  1
1   1   cccccccccc  1
1   1   dddddddddd  1
1   1   NULL    2
1   2   eeeeeeeeee  1
1   2   ffffffffff  1
1   2   gggggggggg  1
2   1   hhhhhhhhhh  1
2   1   NULL    3

答案 2 :(得分:0)

动态方法

 SELECT d.doc, d.pos, s.serial, 1 qty
    FROM #data d
    INNER JOIN #serial s ON s.doc = d.doc and s.pos = d.pos
    UNION
    select t1.doc,t1.pos,null,t1.qty-ss from
    (
        SELECT d.doc,d.pos, SUM(1) SS , d.qty
        FROM #data d
        INNER JOIN #serial s ON s.doc = d.doc and s.pos = d.pos
        group by d.doc,d.pos,d.qty
    )t1 where SS<>qty
    Order by d.doc,d.pos,s.serial