你能帮我看看我走的路是否正确吗?我是 SQL 的新手,所以有很多事情对我来说并不明显。
假设我有两个表。
第一个是订阅者列表:
subscribers
+--------+------------+
|subscID | name |
+--------+------------+
| 123 | SomeName00 |
| 456 | SomeName01 |
| 789 | SomeName02 |
| 012 | SomeName03 |
| 345 | SomeName04 |
+--------+------------+
第二个是通话记录(或类似的东西),包括订阅者的收入和支出以及交易 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 |
+--------+---------------------+--------+-----------+----------+
最初我有两个任务:
1.统计每个订阅者的交易次数
2012 年 3 月(包括第一张表中不在
第二张 table ,比如 123 SomeName00
,还有那些没有任何
2012 年 3 月的交易,例如 789 SomeName02
)。
2. 计算 2012 年 3 月每个订阅者的期末余额 (同样,包括第一张表中不在 二表和三月份没有任何交易的表 2012)。
我已经这样处理了第一个:
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 |
+------------+------------+
然后我尝试重用代码,以便通过将 COUNT(transactions.subscID)
更改为 transactions.balance
并向 LEFT 添加一个条件来解决第二个任务JOIN (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%"
条件。此外,我的结果表中有 NULL(我想,这是因为我不再使用 COUNT
来计算所有行,包括 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 |
+------------+----------+ +------------+----------+
所以,我有两个问题:
- 我需要检索月末余额值
- 并将 NULL 值打印为
0
。
如果你能告诉我正确的方向,我将不胜感激。
最佳答案
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
来源
关于mysql - 获取给定时间段内分组项目的最新值,包括。零和空值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13567474/