3

私が正しい道を進んでいるかどうかを調べるのを手伝ってくれませんか? 私はSQLを初めて使用するので、私には明らかでないことがたくさんあります。

2 つのテーブルがあるとします。
1 つ目はサブスクライバーのリストです。

      subscribers
+--------+------------+
|subscID |    name    |
+--------+------------+
|   123  | SomeName00 |
|   456  | SomeName01 |
|   789  | SomeName02 |
|   012  | SomeName03 |
|   345  | SomeName04 |
+--------+------------+

2 つ目は通話ログ (またはそのようなもの) で、加入者の収入と支出、トランザクション ID およびアカウントの現在の状態が含まれます。

                        transactions
+--------+---------------------+--------+-----------+----------+
| trnID  | date                |subscID | amount    | balance  |
+--------+---------------------+-------+------------+----------+
| 321456 | 2012-03-13 11:10:00 |   456  |   70.0000 |  90.0000 |
| 234567 | 2012-03-16 15:05:00 |   456  |  -45.0000 |  45.0000 |
| 345678 | 2012-03-19 17:27:00 |   456  |   15.0000 |  60.0000 |
| 654321 | 2012-04-22 17:34:00 |   456  |  -10.0000 |  50.0000 |
| 543210 | 2012-04-15 15:45:00 |   789  |   20.0000 |  30.0000 |
| 567890 | 2012-05-16 13:30:00 |   789  |  -10.0000 |  20.0000 |
| 876543 | 2012-02-29 11:00:00 |   012  |   20.0000 |   5.0000 |
| 678901 | 2012-03-31 09:40:00 |   012  |   10.0000 |  15.0000 |
| 456789 | 2012-03-31 21:09:00 |   012  |  -13.0000 |   2.0000 |
| 432109 | 2012-02-23 14:01:00 |   345  |  -30.0000 |  27.0000 |
| 012345 | 2012-03-24 19:57:00 |   345  |   40.0000 |  67.0000 |
| 765432 | 2012-03-27 13:28:00 |   345  |  -14.0000 |  53.0000 |
+--------+---------------------+--------+-----------+----------+

最初は2つのタスクがありました:

1. 2012 年 3 月のすべてのサブスクライバーのトランザクション数をカウントします (最初のテーブルのサブスクライバーで 2 番目のテーブルに含まれて123 SomeName00いないもの、および のように 2012 年 3 月にトランザクションがなかったサブスクライバーを含む789 SomeName02)。

2. 2012 年 3 月の各サブスクライバーの期末残高をカウントします (ここでも、2 番目のテーブルに含まれていない最初のテーブルのサブスクライバーと、2012 年 3 月にトランザクションがなかったサブスクライバーを含みます)。


私はこの方法で最初のものを処理しました:

SELECT name, COUNT(transactions.subscID) AS num_of_trns
FROM subscribers
LEFT JOIN transactions
ON subscribers.subscID = transactions.subscID 
    AND transactions.date LIKE "2012-03%"
GROUP BY subscribers.subscID

うまくいくようで、次の結果が得られます。

+------------+------------+
|    name    |num_of_trns |
+------------+------------+
| SomeName00 |     0      |
| SomeName01 |     3      |
| SomeName02 |     0      |
| SomeName03 |     2      |
| SomeName04 |     2      |
+------------+------------+

次に、次のように LEFT JOIN ( ) に変更COUNT(transactions.subscID)transactions.balanceてもう 1 つの条件を追加することで、2 番目のタスクを解決するためにコードを再利用しようとしました。transactions.date = MAX(transactions.date)

SELECT name, transactions.balance AS trns_blnc
FROM subscribers
LEFT JOIN transactions
ON subscribers.subscID = transactions.subscID 
    AND transactions.date LIKE "2012-03%"
    AND transactions.date = MAX(transactions.date) --this is incorrect
GROUP BY subscribers.subscID

しかし、このアプローチは完全に間違っていることが判明しました (MySQL は、私が比較しようとしている値を理解していなかっただけだと思います)。

次に、インスタンスの日付 = 古いテーブルの日付という条件で、別のインスタンスをもう一度左結合して、最初のタスクの結果を利用することにtransactionsしました (間違った用語を使用していたらすみません)。

SELECT march_trns.name, balance FROM (
    SELECT name, date
    FROM subscribers
    LEFT JOIN transactions
    ON subscribers.subscID = transactions.subscID 
        AND transactions.date LIKE "2012-03%"
        GROUP BY subscribers.subscID
) AS march_trns
LEFT JOIN transactions AS transactions2
ON march_trns.date = transactions2.date

しかし、すぐにそれを知りmarch_trns.date、その結果、条件balanceを満たしている値の中からランダムに (または、その選択のパターンを見つけることができなかっただけで) 選択されましたLIKE "2012-03%"COUNTさらに、結果のテーブルに NULL がありました (NULLを含むすべての行をカウントする機能を使用しなくなったためだと思います)。

          Have:                          Want:
+------------+----------+      +------------+----------+
| name       | balance  |      | name       | balance  |
+------------+----------+      +------------+----------+
| SomeName00 |     NULL |      | SomeName00 |   0.0000 |
| SomeName01 |  90.0000 |      | SomeName01 |  60.0000 |
| SomeName02 |     NULL |      | SomeName02 |   0.0000 |
| SomeName03 |   2.0000 |      | SomeName03 |   2.0000 |
| SomeName04 |  67.0000 |      | SomeName04 |  53.0000 |
+------------+----------+      +------------+----------+

だから、私は2つの問題があります:

  • 月末の残高値を取得する必要があります
  • NULL 値を0s として出力します。

正しい方向性を教えていただければ幸いです。

4

1 に答える 1

1
SELECT  name, 
        COALESCE(COUNT(transactions.subscID), 0) AS num_of_trns,
        COALESCE(d.balance,0)
FROM    subscribers
        LEFT JOIN transactions
            ON subscribers.subscID = transactions.subscID 
                AND transactions.date LIKE "2012-03%"
        LEFT JOIN
        (
            SELECT  a.subscID, a.balance
            FROM    transactions a
                    INNER JOIN
                    (
                        SELECT subscID, MAX(date) maxDate
                        FROM transactions
                        WHERE transactions.date LIKE "2012-03%"
                        GROUP BY subscID
                    ) b ON a.subscID = b.subscID AND
                            a.date = b.maxDate

        ) d ON subscribers.subscID = d.subscID
GROUP BY subscribers.subscID
ORDER BY Name

またはを使用YEARしてMONTH

SELECT  name, 
        COALESCE(COUNT(transactions.subscID), 0) AS num_of_trns,
        COALESCE(d.balance,0)
FROM    subscribers
        LEFT JOIN transactions
            ON subscribers.subscID = transactions.subscID 
                AND YEAR(transactions.date) = 2012 AND
                    MONTH(transactions.date) = 3
        LEFT JOIN
        (
            SELECT  a.subscID, a.balance
            FROM    transactions a
                    INNER JOIN
                    (
                        SELECT subscID, MAX(date) maxDate
                        FROM transactions
                        WHERE YEAR(transactions.date) = 2012 AND
                              MONTH(transactions.date) = 3
                        GROUP BY subscID
                    ) b ON a.subscID = b.subscID AND
                            a.date = b.maxDate

        ) d ON subscribers.subscID = d.subscID
GROUP BY subscribers.subscID
ORDER BY Name

ソース

于 2012-11-26T15:14:49.303 に答える