2017-05-24 174 views
1

我有一個查詢可以爲我們的客戶生成損益表,但我在加入訂單表時遇到問題,導致SUM乘以費用分錄數量。MySQL查詢:SUM計數重複行

我有以下表格:

  • user_report_categories, 「URC」,這是類的標題對於誰報告
  • user_report_expenses, 「茜」,這是個人的開支,以 「adjusted_cost」 用戶和一個「費用日期」。這些可能會或可能不會有與它們相關的訂單,但在這種情況下,我們只關心與訂單相關的費用。每個訂單可能有多個開支,但每個開支/訂單將始終處於不同的類別。
  • 訂單,「O」,它有一個「agreed_fee」,「平衡」,當然,一個「id」

報告需要用戶選擇的日期範圍內具有每月一列,用單元格中的計算值。

查詢原樣如下:

SELECT 
SUBSTRING(MONTHNAME(STR_TO_DATE(m, '%m')), 1, 3) AS month, 
COUNT(o.id) AS "# of Orders", 
ROUND(SUM(o.agreed_fee) - SUM(o.balance), 2) AS "Total Income", 
ROUND(SUM(ure.adjusted_cost), 2) AS "Total Expenses", 
ROUND(SUM(o.agreed_fee) - SUM(o.balance) - SUM(ure.adjusted_cost), 2) AS "Profit & Loss", 
"" AS "", 
ROUND(SUM(ure.adjusted_cost)/COUNT(ure.id), 2) AS "% of Expenses per Order", 
ROUND((SUM(o.agreed_fee) - SUM(o.balance))/COUNT(ure.id), 2) AS "Average Fee per Order", 
ROUND(((SUM(o.agreed_fee) - SUM(o.balance))/COUNT(ure.id)) - (SUM(ure.adjusted_cost)/COUNT(ure.id)), 2) AS "Average P/L per Order" 

FROM ( 
    SELECT y, m FROM 
    (SELECT YEAR('2016-01-01') y) years, 
    (SELECT 1 m UNION ALL SELECT 2 UNION ALL SELECT 3) months 
) ym 

LEFT JOIN user_report_categories AS urc ON urc.user_id = 48 
LEFT JOIN user_report_entries AS ure ON ure.user_category_id = urc.id AND YEAR(ure.expense_date) = y AND MONTH(ure.expense_date) = m 
LEFT JOIN orders AS o ON o.id = ure.order_id 
WHERE urc.report_type = 'expense' AND urc.user_id = 48 AND ure.order_id IS NOT NULL 
GROUP BY y, m 

和結果:

month,# of Orders,Total Income,Total Expenses,Profit & Loss,,% of Expenses per Order,Average Fee per Order,Average P/L per Order 
Jan,387,36400.00,5921.17,30478.83,,15.30,94.06,78.76 
Feb,559,55327.50,8165.12,47162.38,,14.61,98.98,84.37 
Mar,736,74785.00,10261.07,64523.93,,13.94,101.61,87.67 

我確定通過將訂單ID的組由該訂單被乘以的支出數

GROUP BY y, m, o.id 

並查看每行有多個訂單的新結果:

month,# of Orders,Total Income,Total Expenses,Profit & Loss,,% of Expenses per Order,Average Fee per Order,Average P/L per Order 
Jan,6,360.00,31.95,328.05,,5.33,60.00,54.68 
Jan,1,0.00,30.24,-30.24,,30.24,0.00,-30.24 
Jan,6,1200.00,141.74,1058.26,,23.62,200.00,176.38 
Jan,6,540.00,160.97,379.03,,26.83,90.00,63.17 
Jan,6,540.00,98.77,441.23,,16.46,90.00,73.54 
Jan,8,720.00,167.44,552.56,,20.93,90.00,69.07 
... etc ... 

或者,當我從組通過刪除o.id,而是改變訂單行#數不同:

COUNT(DISTINCT o.id) AS "# of Orders", 

我得到正確的價值觀爲訂單#,但當然由於重複,SUM順序表值的其他值仍然不正確。

month,# of Orders,Total Income,Total Expenses,Profit & Loss,,% of Expenses per Order,Average Fee per Order,Average P/L per Order 
Jan,71,36400.00,5921.17,30478.83,,15.30,94.06,78.76 
Feb,105,55327.50,8165.12,47162.38,,14.61,98.98,84.37 
Mar,146,74785.00,10261.07,64523.93,,13.94,101.61,87.67 

我不知道如果我即使考慮一個好方法這一點,但在一個查詢中這樣做產生是一個巨大的優勢,對我來說,所以我試圖拼湊一起。我怎樣才能得到它在不同的訂單ID的SUM訂單表值,否則更正查詢以正確計算?謝謝!


回答

@Sal踢我了,我有結束最後的查詢如下。我認爲它也涵蓋了評論中出現的所有問題。

SELECT 
SUBSTRING(MONTHNAME(STR_TO_DATE(m, '%m')), 1, 3) AS month, 
orders AS "# of Orders", 
round(total_income,2) AS "Total Income", 
round(total_expenses,2) AS "Total Expenses", 
round(total_income-total_expenses,2) AS "Profit & Loss", 
"" AS "", 
round(total_expenses/orders,2) AS "% of Expenses per Order", 
round(total_income/orders,2) AS "Average Fee per Order", 
round((total_income/orders)-(total_expenses/orders), 2) AS "Average P/L per Order" 

     FROM ( 
      SELECT m, 
      (SELECT count(o.id) 
       FROM orders o 
       WHERE year(o.datetime) = ym.y 
       AND month(o.datetime) = ym.m AND o.user_id = 48 
       AND o.cancelled = 0 
      ) AS orders, 
      (SELECT IFNULL(sum(o.agreed_fee - o.balance), 0) 
       FROM orders AS o 
       WHERE year(o.datetime) = ym.y 
       AND month(o.datetime) = ym.m 
       AND o.user_id = 48 
       AND o.cancelled = 0 
      ) AS total_income, 
      (SELECT IFNULL(sum(ure.adjusted_cost),0) 
       FROM user_report_entries AS ure 
       INNER JOIN user_report_categories AS urc ON urc.id = ure.user_category_id 
        WHERE year(ure.expense_date) = ym.y 
       AND month(ure.expense_date) = ym.m 
       AND urc.user_id = 48 AND urc.id NOT IN (6287)) AS total_expenses 
      FROM (SELECT 2017 y, 1 m UNION SELECT 2017, 2 UNION SELECT 2017, 3 
      ) ym 

      GROUP BY y, m 
     ) t 
+0

'COUNT(o.id)'和'GROUP BY','COUNT(o.id)''沒有GROUP BY'和'COUNT (DISTINCT)'互不相同,並且會返回不同的值。根據上面的查詢,理解預期的輸出是不容易的,因此添加更多信息(即表格模式和/或輸出)或者只是一個[SQLFiddle](http://sqlfiddle.com/)。 –

+0

我感覺到一個問題:'user_report_entries'有成本並且與訂單有關。假設您的訂單中的「約定的費用」爲100.對於此訂單,您有一個2016-01的報告條目,其中「adjusted_cost」爲40,另一個報告條目爲2016-02,「adjusted_cost」爲50.所以你計算兩個月中的哪一個與'agree_fee'?您需要一個算法(可能僅在第一次或最後一次報告的月份或訂單日期的月份計算訂單及其所有報告條目)。 –

+0

@DarshanMehta這些是我嘗試過的一些事情和他們的結果。我需要查詢的行爲方式是每個訂單隻計算一次,即使每個訂單有多個費用。 – Lea

回答

1

我希望對您有所幫助:

SELECT substring(monthname(str_to_date(m,'%m'), 1, 3) month 
    , orders "# of Orders" 
    , round(total_income,2) "Total Income" 
    , round(total_expenses,2) "Total Expenses" 
    , round(total_income-total_expenses,2) "Profit & Loss" 
    , round(total_expenses/orders,2) "% of Expenses per Order" 
    , round(total_income/orders,2) "Average Fee per Order" 
    , round((total_income/orders)-(total_expenses/orders), 2) "Average P/L per Order" 
    FROM (SELECT m 
       , (SELECT count(distinct ure.order_id) 
        FROM user_report_entries ure 
        WHERE year(ure.expense_date) = ym.y 
         AND month(ure.expense_date) = ym.m 
       ) orders 
       , (SELECT sum(o.agreed_fee - o.balance) 
        FROM user_report_entries ure 
         INNER JOIN orders o 
         ON o.id = ure.order_id    
        WHERE year(ure.expense_date) = ym.y 
         AND month(ure.expense_date) = ym.m 
       ) total_income 
       , sum(ure.adjusted_cost) total_expenses 
      FROM (SELECT 2016 y, 1 m 
        UNION 
        SELECT 2016, 2 
        UNION 
        SELECT 2016, 3 
       ) ym 
      LEFT JOIN user_report_entries ure 
       ON year(ure.expense_date) = ym.y 
       AND month(ure.expense_date) = ym.m 
      LEFT JOIN user_report_categories urc 
       ON urc.id = ure.user_category_id 
      WHERE urc.user_id = 48 
      AND urc.report_type = 'expense' 
      GROUP BY y, m 
     ) t 
+0

這會把我踢向正確的方向,我調整了一下,現在就開始工作了,謝謝! – Lea