将第一列(金额)中的值的总和减去另一个第二列(产品),并将条件与另一个第三列(过程)分组

时间:2018-09-06 07:32:22

标签: sql sql-server

有人可以帮我解决这个问题吗?

注意:首先,我要为我的英语道歉... :)

说明

情况

我有生产记录表。 该表中包含每个生产过程中已处理量的数据。

生产过程必须按时间顺序排列,例如:过程- 1 →过程- 2 →过程- 3 →等。< / em>,但是产品的生产不必按时间顺序进行。

问题

我想在某个进程(除 Process- 1 之外的任何 Process )上使用查询,并且我想知道多少每个产品均可用于此过程。

我的意思是:我想知道从前一个流程中减去的加工产品数量减去当前流程中的加工产品数量。

示例

数据表

生产: | DataID | Product | Amount | Process | |--------|---------|--------|---------| | 1 | P1 | 50 | 1 | | 2 | P2 | 40 | 1 | | 3 | P1 | 25 | 1 | | 4 | P1 | 60 | 2 | | 5 | P2 | 20 | 1 | | 6 | P3 | 75 | 1 | | 7 | P2 | 30 | 2 | | 8 | P1 | 35 | 3 | | 9 | P2 | 10 | 3 | | 10 | P3 | 50 | 2 |

要求

查询过程2

过程2: | Process | Product | Amount | |---------|---------|--------| | 2 | P1 | 15 | | 2 | P2 | 30 | | 2 | P3 | 25 |

因为:

P1 = 50 + 25-60 = 15

P2 = 40 + 20-30 = 30

P3 = 75-50 = 25

查询过程3

过程3: | Process | Product | Amount | |---------|---------|--------| | 3 | P1 | 25 | | 3 | P2 | 20 | | 3 | P3 | 50 |

因为:

P1 = 60-35 = 25

P2 = 30-10 = 20

P3 = 50 = 50

我尝试过...

使用SELF JOIN

(按产品分组)

SELECT SUM(A.Amount)-SUM(B.Amount) FROM Data A, Data B
WHERE A.Process = 1 AND B.Process = 2
GROUP BY A.Product

看起来不错,但是结果是错误的...

使用子选择#1

SELECT (X - Y) AS 'Amount' FROM
(SELECT SUM(Amount) AS X FROM Data WHERE Process = 1),
(SELECT SUM(Amount) AS Y FROM Data WHERE Process = 2)

它有效,但仅适用于 Product- 1 (可能是因为它在数据表中排在首位)。

使用子选择#2

SELECT
((SELECT SUM(Amount) FROM Data WHERE Process = 1 GROUP BY Product) - 
(SELECT SUM(Amount) FROM Data WHERE Process = 2 GROUP BY Product)) AS 'Amount'

使用子选择#1 ...

的结果相同

非常感谢

2 个答案:

答案 0 :(得分:0)

您可以使用此方法,将数字2更改为您的流程号(4个替换位置):

此功能适用于SQLServer 2005 +

WITH total_in_process AS 
(
    SELECT product, process,
        SUM(amount) AS amount
    FROM table_name
    GROUP BY product, process
)
SELECT 2 AS process,
    t1.product AS product,
    COALESCE(t1.amount, 0) - COALESCE(t.amount, 0) AS amount
FROM total_in_process t1
LEFT JOIN total_in_process t
ON t1.product = t.product AND t1.process = t.process - 1
WHERE COALESCE(t.process, 2) = 2 AND t1.process = 2 - 1 
ORDER BY t1.product;

这是SQLFiddle

Edited:如果您有流程4,并且想从上一个流程(流程2/1而不是3)中获取剩余价值,则应该使用以下查询:

WITH all_product AS 
(
    SELECT DISTINCT product
    FROM table_name
)
, total_in_process AS 
(
    SELECT product, process,
        SUM(amount) AS amount
    FROM table_name
    GROUP BY product, process
)
, last_process AS 
(
    SELECT product, 
        MAX(process) AS last_process
    FROM total_in_process
    WHERE process < 4
    GROUP BY product
)
, last_process_value AS 
(
    SELECT t.product, t.process, t.amount
    FROM total_in_process t 
    INNER JOIN last_process l
    ON t.product = l.product AND t.process = l.last_process
)
SELECT 4 AS process,
    p.product,
    COALESCE(l.amount, 0) - COALESCE(t.amount, 0) AS amount
FROM all_product p
LEFT JOIN total_in_process t
ON p.product = t.product AND t.process = 4 
LEFT JOIN last_process_value l
ON l.product = p.product 
ORDER BY p.product;

答案 1 :(得分:0)

由于某些产品可能处于或可能不在某个流程中,因此我们首先必须收集所有有效产品,然后才计算结果 这是我刚刚在您的数据上测试过的代码:

with all_prod as (select distinct Product from t1)
select  
  ap.Product, coalesce(B.Amount,0) - coalesce(A.Amount,0) Amount
  from all_prod ap
  left join (
  select SUM(Amount) Amount, Product, 2 Process 
    from t1 
    where Process = 2
    group by Product, Process) A on A.Product = ap.Product
  left join (
  select SUM(Amount) Amount, Product, 2 Process 
    from t1 
    where Process = 1
    group by Product, Process) B on ap.Product = B.Product 

它会计算流程2的值,要获取流程3的结果,您应该在where子句中更改值