添加带有计算的汇总列

Add summarizing column with calculation

我需要显示发票每一行的序列号。这意味着,在一个位置上可以有多个序列号。除了序列号之外,还需要有一个数量,显然总是一个。不幸的是,有些行的项目可能多于序列号。如果在运输过程中未扫描序列号,就会发生这种情况。在我的输出中,我需要为这些位置添加一行,其中显示剩余项目的数量。比方说,有一个位置有 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

你在找这个..?

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

输出

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

动态方法

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