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 - 对两个表中的两列求和并写入新列的主要内容,如果未能解决你的问题,请参考以下文章
复合求和:我想创建一个复合查询,它从两个不同的表中获取两列的单独总和,然后对它们求和
如何对两列求和并通过减去它们的聚合 SQL 和 C# 在第三列中显示结果?