2013-10-29 71 views
0

我確定這是一個常見問題,但我無法以我描述的方式找到解決方案。我的查詢是這樣的:MySQL:使用兩列的值來計算第三個

SELECT 
    (
     SELECT SUM(finance_transaction_components.invoiced_price) 
     FROM finance_transactions 
     JOIN finance_transaction_components ON finance_transaction_components.transaction_id = finance_transactions.id 
     JOIN agents ON agents.id = finance_transactions.agent_id 
     WHERE DATE_FORMAT(finance_transactions.completed_date, "%Y-%m-%d") BETWEEN "2013-10-01" AND "2013-10-29" 
    ) AS "Total Costs", 

    (
     SELECT SUM(finance_transactions.agent_price) 
     FROM finance_transactions 
     JOIN agents ON agents.id = finance_transactions.agent_id 
     WHERE finance_transactions.product_id != 10 
     AND DATE_FORMAT(completed_date, "%Y-%m-%d") BETWEEN "2013-10-01" AND "2013-10-29" 
    ) AS "Total Revenue", 

    (
     SELECT SUM(finance_transactions.agent_price) 
     FROM finance_transactions 
     JOIN agents ON agents.id = finance_transactions.agent_id 
     WHERE finance_transactions.product_id != 10 
     AND DATE_FORMAT(completed_date, "%Y-%m-%d") BETWEEN "2013-10-01" AND "2013-10-29" 
     AND IF(finance_transactions.lldrg > 0, IF(finance_transactions.lldrg = 1, 0, 1) ,1) = 1 
    ) - (SELECT SUM(finance_transaction_components.invoiced_price) 
     FROM finance_transactions 
     JOIN finance_transaction_components ON finance_transaction_components.transaction_id = finance_transactions.id 
     JOIN agents ON agents.id = finance_transactions.agent_id 
     WHERE DATE_FORMAT(finance_transactions.completed_date, "%Y-%m-%d") BETWEEN "2013-10-01" AND "2013-10-29" 
    ) AS "Margin" 

FROM finance_transactions 
GROUP BY finance_transactions.agent_id 

這並不重要,什麼列等等。在這種情況下,最重要的一點是這樣的:保證金列需要重複總成本總收入查詢計算,這似乎是一個愚蠢的做法。但顯然我不能只說"Total Revenue" - "Total Costs" AS "Margin

+0

我看到您剛剛刪除了聚合函數。如果每個子查詢返回多於一行的話,您將如何鏈接收入和成本? –

+0

對不起,我現在已經回滾了編輯。我想我可以通過編輯簡化其他讀者的問題。 – Jack

回答

1

你可以簡單地通過使用內部查詢實現,而不必重複代碼同樣的事情:

SELECT TotalCosts, TotalRevenue, TotalCost - TotalRevenue AS Margin 
FROM 
(
    SELECT 
    (
     SELECT SUM(finance_transaction_components.invoiced_price) 
     FROM finance_transactions 
     JOIN finance_transaction_components ON finance_transaction_components.transaction_id = finance_transactions.id 
     JOIN agents ON agents.id = finance_transactions.agent_id 
     WHERE DATE_FORMAT(finance_transactions.completed_date, "%Y-%m-%d") BETWEEN "2013-10-01" AND "2013-10-29" 
    ) AS TotalCosts, 

    (
     SELECT SUM(finance_transactions.agent_price) 
     FROM finance_transactions 
     JOIN agents ON agents.id = finance_transactions.agent_id 
     WHERE finance_transactions.product_id != 10 
     AND DATE_FORMAT(completed_date, "%Y-%m-%d") BETWEEN "2013-10-01" AND "2013-10-29" 
    ) AS TotalRevenue 
) t 

編輯:這個答案是基於第一個版本的問題,在一個與聚集功能。

+0

這個回答很好地解決了當前的問題。但是,對於這種特定情況(最初的說法),最好的方法是避免首先進行額外的子查詢。 – PinnyM

+0

我同意你的意見,我沒有試圖簡化它。在這種特殊情況下,你的答案會更好。 –

1

UPDATE - 此答案基於原始問題的查詢。

作爲@ X.L.Ant已經提出,您可以包裝查詢並在包裝查詢中執行簡單的數學運算。但是,在您的情況下,如果您只是將查詢簡化爲此,則可以更高效地執行此操作:

SELECT agent_id, TotalCost, TotalRevenue, TotalRevenue - TotalCost AS Margin 
FROM (
    SELECT finance_transactions.agent_id 
      SUM(finance_transaction_totals.total_cost) AS TotalCost, 
      SUM(CASE WHEN finance_transactions.product_id = 10 THEN 0 
        ELSE finance_transactions.agent_price) AS TotalRevenue 
    FROM finance_transactions 
    JOIN (SELECT transaction_id, SUM(invoiced_price) AS total_cost 
      FROM finance_transaction_components 
      GROUP BY transaction_id) finance_transaction_totals 
     ON finance_transactions.id = finance_transaction_totals.transaction_id 
    WHERE DATE_FORMAT(finance_transactions.completed_date, "%Y-%m-%d") BETWEEN "2013-10-01" AND "2013-10-29" 
    GROUP BY finance_transactions.agent_id 
) t 
相關問題