Sql 更新表以包含计算的百分比

Sql 更新表以包含计算的百分比,sql,sql-server,sql-update,Sql,Sql Server,Sql Update,我有以下简化表格: ╔══════════╦═══════════╗═══════════╗═══════════╗ ║ Dough ║ Material ║ PerCharge ║ Perc ║ ╠══════════╬═══════════╣═══════════╣═══════════╣ ║ DG10001 ║ GR002152 ║ 2,00 ║ ║ ║ DG10001 ║ GR000133 ║ 9,00 ║

我有以下简化表格:

╔══════════╦═══════════╗═══════════╗═══════════╗
║ Dough    ║ Material  ║ PerCharge ║ Perc      ║
╠══════════╬═══════════╣═══════════╣═══════════╣
║ DG10001  ║ GR002152  ║ 2,00      ║           ║ 
║ DG10001  ║ GR000133  ║ 9,00      ║           ║ 
║ DG10001  ║ GR000133  ║ 9,00      ║           ║ 
║ DG10002  ║ GR002152  ║ 2,50      ║           ║ 
╚══════════╩═══════════╝═══════════╝═══════════╝
面团材料是多种关系中的一种,PerCharge是每个容器使用的原料重量

我想根据每个独特面团的总使用量来计算每一行的百分比

我用下面的公式来计算百分比

SELECT D.Dough
       ,Material
       ,PerCharge
       ,PerCharge/Total as Percentage
  FROM 
(Select Dough
       ,sum(PerCharge) as Total
From [PP_Materials].[dbo].[Deegregels]

group by Dough
) as D

left join

(SELECT Dough
      ,Material
     ,PerCharge
FROM [PP_Materials].[dbo].[Deegregels]
) as D2
On D.Dough = D2.Dough

order by D.Dough
现在我只需要更新原始表以包含这个计算出的百分比,但我不知道如何制定update语句

您能给予的任何帮助都将不胜感激

编辑:简化示例的结果

╔══════════╦═══════════╗═══════════╗═══════════╗
║ Dough    ║ Material  ║ PerCharge ║ Perc      ║
╠══════════╬═══════════╣═══════════╣═══════════╣
║ DG10001  ║ GR002152  ║ 2,00      ║     10%   ║ 
║ DG10001  ║ GR000133  ║ 9,00      ║     45%   ║ 
║ DG10001  ║ GR000133  ║ 9,00      ║     45%   ║ 
║ DG10002  ║ GR002152  ║ 2,50      ║     10%   ║ 
╚══════════╩═══════════╝═══════════╝═══════════╝

您应该能够尝试以下方法:

CREATE TABLE #Dough
(
    Dough VARCHAR(10) NULL,
    PerCharge DECIMAL(10,2) NULL,
    [Percentage] DECIMAL(10,2) NULL
)

INSERT INTO #Dough
VALUES
('DG10001',2,NULL),('DG10001',9,NULL),('DG10001',9,NULL),('DG10002',2,NULL)

SELECT *
FROM #Dough

;WITH Total AS
(
    SELECT   Dough
            ,Total = SUM(PerCharge)
    FROM #Dough
    GROUP BY Dough
)
UPDATE D1
SET [Percentage] = D1.PerCharge/T1.Total
FROM #Dough D1
JOIN Total  T1 ON D1.Dough = T1.Dough

您应该能够尝试以下方法:

CREATE TABLE #Dough
(
    Dough VARCHAR(10) NULL,
    PerCharge DECIMAL(10,2) NULL,
    [Percentage] DECIMAL(10,2) NULL
)

INSERT INTO #Dough
VALUES
('DG10001',2,NULL),('DG10001',9,NULL),('DG10001',9,NULL),('DG10002',2,NULL)

SELECT *
FROM #Dough

;WITH Total AS
(
    SELECT   Dough
            ,Total = SUM(PerCharge)
    FROM #Dough
    GROUP BY Dough
)
UPDATE D1
SET [Percentage] = D1.PerCharge/T1.Total
FROM #Dough D1
JOIN Total  T1 ON D1.Dough = T1.Dough

您也可以将其包装成cte

with updatestatement as  (SELECT D.Dough
       ,Material
       ,PerCharge
       ,PerCharge/Total as Percentage
  FROM 
(Select Dough
       ,sum(PerCharge) as Total
From [dbo].[Deegregels]

group by Dough
) as D

left join

(SELECT Dough
      ,Material
     ,PerCharge
FROM [dbo].[Deegregels]
) as D2
On D.Dough = D2.Dough
)

update b
set perc = a.percentage

from updatestatement a inner join dbo.[Deegregels] b on a.dough = b.dough and a.material = b.material

您也可以将其包装成cte

with updatestatement as  (SELECT D.Dough
       ,Material
       ,PerCharge
       ,PerCharge/Total as Percentage
  FROM 
(Select Dough
       ,sum(PerCharge) as Total
From [dbo].[Deegregels]

group by Dough
) as D

left join

(SELECT Dough
      ,Material
     ,PerCharge
FROM [dbo].[Deegregels]
) as D2
On D.Dough = D2.Dough
)

update b
set perc = a.percentage

from updatestatement a inner join dbo.[Deegregels] b on a.dough = b.dough and a.material = b.material

更简洁的版本:

USE Sandbox;
GO
--Create sample table and data
CREATE TABLE #Dough (Dough varchar(10),
                     Material varchar(10),
                     PerCharge decimal(5,2),
                     Perc decimal(3,2));

INSERT INTO #Dough (Dough,
                    Material,
                    PerCharge)
VALUES ('DG10001','GR002152',2.00), 
       ('DG10001','GR000133',9.00), 
       ('DG10001','GR000133',9.00), 
       ('DG10002','GR002152',2.50);
GO
--The solution

WITH CTE AS(
    SELECT D.Dough, D.Material, D.PerCharge, Perc,
           PerCharge / SUM(PerCharge) OVER (PARTITION BY Dough) AS NewPerc
    FROM #Dough D)
UPDATE CTE
SET Perc = NewPerc
GO
--Check the data
SELECT *
FROM #Dough
GO
--Clean up
DROP TABLE #Dough;

当您可以使用窗口功能时,无需扫描表格两次。

更简洁的版本:

USE Sandbox;
GO
--Create sample table and data
CREATE TABLE #Dough (Dough varchar(10),
                     Material varchar(10),
                     PerCharge decimal(5,2),
                     Perc decimal(3,2));

INSERT INTO #Dough (Dough,
                    Material,
                    PerCharge)
VALUES ('DG10001','GR002152',2.00), 
       ('DG10001','GR000133',9.00), 
       ('DG10001','GR000133',9.00), 
       ('DG10002','GR002152',2.50);
GO
--The solution

WITH CTE AS(
    SELECT D.Dough, D.Material, D.PerCharge, Perc,
           PerCharge / SUM(PerCharge) OVER (PARTITION BY Dough) AS NewPerc
    FROM #Dough D)
UPDATE CTE
SET Perc = NewPerc
GO
--Check the data
SELECT *
FROM #Dough
GO
--Clean up
DROP TABLE #Dough;


当您可以使用窗口功能时,无需扫描表格两次。

此处的预期结果集是什么?添加了示例结果,平均每个面团有6种材料,因此没有将其包含在简化版本中。我假设10%实际上应该是100%。否则这些数据就没有意义了。你的预期结果是什么?添加了样本结果,平均每个面团有6种材料,所以没有包括在简化版本中。我假设10%应该是100%。否则,这些数据就没有意义了。谢谢,这是我工作的方向,但它确实给出了一个错误:Msg 4418,16级,状态1,第1行派生表“D”不可更新,因为它包含聚合,或DISTINCT或GROUP BY子句,或者PIVOT或UNPIVOT运算符。我编辑了我的答案并简化了代码,这样您就不需要使用子查询了。我添加了我的测试代码,以便您可以使用它。是的,我已经测试了它,它运行时没有任何问题,并返回每个面团的百分比。如果您指的是我,不包括我选择的材料。谢谢,这是我工作的方向,但它确实给出了一个错误:Msg 4418,16级,状态1,第1行派生表“D”不可更新,因为它包含聚合,或DISTINCT或GROUP by子句,或者PIVOT或UNPIVOT运算符。我编辑了我的答案并简化了代码,这样您就不需要使用子查询了。我添加了我的测试代码,以便您可以使用它。是的,我已经测试了它,它运行时没有任何问题,并返回每个面团的百分比。如果您指的是我,则不包括我选择的材料。谢谢,我也尝试使用cte,但无法将其应用到更新语句中。这非常有效。谢谢,我也尝试过使用cte,但无法将其应用到update语句中。这非常有效。非常感谢,我使用了前面提供的CTE答案来更新它,但此解决方案似乎更干净,现在要尝试理解逻辑。@A.vaneveld不客气。很明显,我的脑海里闪过一个念头,因为我两次参考了表格。我现在已经改变了这一点,所以它不会(而且更简洁)。非常感谢,我使用了前面提供的CTE答案来更新它,但这个解决方案似乎更干净,现在要尝试理解逻辑。@A.vaneveld不客气。很明显,我的脑海里闪过一个念头,因为我两次参考了表格。我现在已经改变了这一点,所以它不会(而且更简洁)。