2017-05-24 11 views
1

私は、顧客の損益計算書を生成するクエリを持っていますが、SUMに費用エントリの数を掛けて注文テーブルに加わることに問題があります。MySQLクエリ:重複行をカウントするSUM

私は、次の表があります。 "adjusted_cost" と

  • user_report_expensesを報告ユーザーのカテゴリのタイトルである

    • user_report_categories、 "URC"、個々の経費である "UREを" と、 「経費支出日」。これらの注文には、注文が関連付けられている場合と関連付けられていない場合がありますが、この場合、注文に関連付けられた費用のみが対象となります。注文ごとに複数の費用がかかる場合がありますが、各費用/注文は常に異なるカテゴリになります。
    • 「agreed_fee」、「バランス」を有する注文、「O」、そしてもちろん、「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 
    

    結果:私はグループごとに注文IDを追加することにより、注文は費用の数で乗算されたと判断

    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 
    

    GROUP BY y, m, o.id 
    

    となり、1行に複数の注文を表示する新しい結果が表示されます。

    また
    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 
    

    私は、私もこれまでの良好なアプローチを取って、しかし、1つのクエリで、この世代をやっている場合は、私にとって大きな利点ですので、私はそれを一緒につなぎしようとしていることを確認していません。別の注文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'はコストがあり、注文に関連しています。 'agree_fee'が100であるオーダーがあるとしましょう。このオーダーの場合、2016-01のレシピエントリーには' adjusted_cost'が40、もう一つのレポートエントリーに2016-02と 'adjusted_cost'の50があります。 2ヶ月のうちどれを計算すれば 'agree_fee'ですか?これにはアルゴリズムが必要です(注文と、最初または最後のレポートエントリの月または注文日の月にのみすべてのレポートエントリを計算することがあります)。 –

    +0

    @DarshanMehtaこれは私が試したことのいくつかとその結果でした。注文ごとに複数の費用があっても、各注文は1回だけカウントまたは合計されるように動作するようにクエリが必要です。 – 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