SQL - 对两个表中的两列求和并写入新列

Posted

技术标签:

【中文标题】SQL - 对两个表中的两列求和并写入新列【英文标题】:SQL - SUM two columns from two tables and write in new Column 【发布时间】:2018-03-22 19:29:08 【问题描述】:

我有以下情况需要解决。我有一个包含产品信息的表 A,我有一个包含客户购买历史记录的表 B。现在我需要在新列“Sum_product_X”中计算购买频率的总和与每个ClientID 的产品价值。所以在这种情况下我们知道A客户已经购买了Product A 5次,所以我们需要在sum_producta列中计算5 * 5$的总和

  Table A (Product Price Table)
    ----------------------------
    ProductA | ProductB | ProductC

    5$ | 10$ | 15$         



    Table B (Client purchase history)
    -----------------------
    ClientID | Frequency_ProductA |Frequency_ProductB | Sum_ProductA | Sum_ProductB

    Abc123 | 5 | 10 | to be calculated: 5*5 | to be calculated 10*10

需要补充的是,我发现环境的SQL支持有以下规则:

仅对帐户中的数据扩展或数据视图的 SELECT 语句 或在父帐户中嵌套查询 UNION JOIN GROUP BY

表 A 可以修改。这意味着结构也可能如下:

Table A 
-----------------------

Productname | Price
product A | 5
product B | 10
product C | 15

【问题讨论】:

你有修复产品或更多? 最好的方法是创建一个视图,我认为您不会获得实际存储在表格中所需的功能 @WhatsThePoint 为什么会这样? @Sami 他需要将其作为存储过程来更新存储的值,不是吗? 你真的应该重新设计你的桌子!表 A 到列 Product 和 Price、行 A、5$ 和 B、10 $... 和表 B 到 ClientID、Frequency_of_Product、Sum_of_Product。 【参考方案1】:

在传统的关系数据库中,一切都与规范化有关。或者换一种说法,你应该只有一个权威来源。通过创建一个新列,您将拥有多个“正确数据”来源。例如,如果频率增加,而您的代码忘记更新列,那么谁能说现在哪个值是正确的?

建议改为让 RDBMS 执行work for you with a VIEW。您当前的模式需要更好地规范化才能利用这一点;我会在下面解决这个问题。

CREATE VIEW product_sales AS
  SELECT
   tabA.product_name,
   tabA.product_price,
   tabB.clientID,
   tabC.frequency,
   tabA.product_price * tabC.count AS sum_product_x
  FROM
    tableA AS tabA,
    tableB AS tabB,
    tableC AS tabC
  WHERE
      tabA.product_id = tabC.product_id
  AND tabB.clientID = tabC.client_id;

现在,在您的查询中,您将 VIEW 视为另一个用于 SELECT 的 TABLE:

SELECT * FROM product_sales ORDER BY 5 DESC, 1 ASC LIMIT 5;

很遗憾,您当前的设计似乎每个产品都有一个列。这通常是一个禁忌。您要为每个新产品添加一列吗?我当然希望不会。相反,将您的数据规范化到单独的表中,并使用主键和外键链接:

CREATE TABLE products (
  product_id     CHAR(5)     PRIMARY KEY,
  product_name   VARCHAR(32) NOT NULL,
  product_price  INTEGER     NOT NULL
);

CREATE TABLE clients (
 client_id      VARCHAR(8) PRIMARY KEY,
 client_name    VARCHAR(32) NOT NULL,
);

CREATE TABLE client_purchaces (
 client_id     VARCHAR(8) NOT NULL,
 product_id    CHAR(5)    NOT NULL,
 count         INTEGER    NOT NULL,

 FOREIGN KEY (client_id) REFERENCES clients(client_id),
 FOREIGN KEY (client_id) REFERENCES products(product_id),
 CONSTRAINT CHECK (count >= 0)
);

使用这种结构,当有新产品出现时,您只需添加一行 (INSERT INTO products ...),而不是更改架构 (ALTER TABLE ...)。此外,当客户进行购买时,您只需插入或更新一个整数,而不是覆盖行或更改您的架构。此外,通过像这样更规范化的设计,您可以让数据库为您完成工作(例如,CREATE VIEW ...

【讨论】:

感谢这个非常复杂的解决方案!不幸的是,我的查询需要以 Select 开头。 @Christian 您的查询以 SELECT 开头。例如,SELECT * FROM product_sales。您还会注意到 VIEW 只是变相的 SELECT 语句。看看上面的定义。【参考方案2】:

如果你不想/不能重新设计你的表,你可以试试这个:

UPDATE table_b
SET SUM_ProductA = (Frequency_Product_A * (SELECT ProductA FROM table_a)),
    SUM_ProductB = (Frequency_Product_B * (SELECT ProductB FROM table_a)),
    SUM_ProductC = (Frequency_Product_C * (SELECT ProductC FROM table_a))

否则我真的推荐@hunteke的答案!!!!!! (我在评论中也提到了这一点)

【讨论】:

【参考方案3】:

你可以试试

UPDATE tableB 
SET sum_productA = (SELECT Price * Frequency_ProductA FROM tableA WHERE Product = 'ProductA'),
SET sum_productB = (SELECT Price * Frequency_ProductB FROM tableA WHERE Product = 'ProductB');

计算列 Sum_ProductA 和 Sum_ProductB。

但是它假设 Product 是你的表 A 的键

【讨论】:

以上是关于SQL - 对两个表中的两列求和并写入新列的主要内容,如果未能解决你的问题,请参考以下文章

如何对来自不同表MySQL的两列求和

复合求和:我想创建一个复合查询,它从两个不同的表中获取两列的单独总和,然后对它们求和

如何对两列求和并通过减去它们的聚合 SQL 和 C# 在第三列中显示结果?

SQL使用group by获取SUM,但有条件地对两列之一的内容求和

sql实现多字段求和并查询

需要对所有负电荷求和并创建新列并用正电荷复制