2017-10-11 78 views
0

我有以下情况需要解决。我有一个带有产品信息的表A,我有一个带有客户购买历史的表B。现在我需要在一个新的专栏“Sum_product_X”中计算购买次数的总和与每个ClientID的产品价值。所以在这种情况下,我们知道一个客户买了Product A 5倍,所以我们需要在列sum_producta计算的5 * 5$SQL-SUM两列从两个表中写入新列

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

+0

您有修复产品或更多? –

+0

做到这一点的最好方法是创建一个视图,我不认为你会得到实际存储在表中的所需函数 – WhatsThePoint

+0

@WhatsThePoint为什么这样? – Sami

回答

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用途:

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

+0

感谢这个非常复杂的解决方案!不幸的是我的查询需要从Select开始。 – Christian

+0

@Christian您的查询**将**以SELECT开头。例如,'SELECT * FROM product_sales'。你还会注意到VIEW只是一个伪装的SELECT语句。看看上面的定义。 – hunteke

0

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

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的答案!!!!!! (我也是在我的评论中提到这一点)

0

您可以尝试

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。

但是,它假设产品是您的表的关键A