2017-10-11 80 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