【发布时间】:2019-02-27 00:20:37
【问题描述】:
我一直在谷歌搜索和查看 SO 帖子,但仍不确定如何完成此操作。
我有一个按(用户、截止日期)分组的结果表, 计算每个用户每个到期日的项目数。
这里是查询:
SELECT
userid as user,
nextduedate as due_date,
count(th.id) as services
FROM
`tblhosting` th
JOIN `tblcustomfieldsvalues` tcfv on th.userid = tcfv.relid
JOIN `tblclients` tc on th.userid = tc.id
WHERE
th.domainstatus = 'Active'
AND (th.nextduedate > date(DATE_SUB(curdate(), INTERVAL 5 day)) AND th.nextduedate < date(DATE_ADD(curdate(), INTERVAL 1 month)))
AND th.packageid NOT IN (132, 130, 129)
AND tcfv.fieldid = 55
AND tcfv.value = "on"
AND tc.separateinvoices = 0
GROUP BY userid, nextduedate
ORDER BY userid asc
结果:
| user | due_date | services |
|------|------------|----------|
| 77 | 2019-03-10 | 4 |
| 81 | 2019-03-05 | 23 |
| 99 | 2019-03-10 | 97 |
| 455 | 2019-03-13 | 9 |
| 478 | 2019-03-10 | 18 |
| 491 | 2019-03-03 | 1 |
| 491 | 2019-03-10 | 143 |
| 541 | 2019-03-02 | 2 |
| 541 | 2019-03-10 | 68 |
| 575 | 2019-03-02 | 46 |
用户 491 有 1 项服务将于 03-03 到期,143 将于 03-10 到期。
我需要计算每个用户出现在列表中的次数,因为我专门寻找到期日超过 1 个的用户。
理论上这实际上很容易,因为我可以像这样进行外部选择:
SELECT userid, COUNT(*)
FROM (inner select) a
GROUP BY a.userid
这会给我:
| user | count(userid)|
|------|--------------|
| 77 | 1 |
| 81 | 1 |
| 99 | 1 |
| 455 | 1 |
| 478 | 1 |
| 491 | 2 |
| 541 | 2 |
| 575 | 1 |
然后我可以将此结果加入原始结果,但它需要运行两次查询。像
Select * FROM
(
Inner Select a
LEFT JOIN
(
SELECT userid, COUNT(*) FROM
(inner select) a
GROUP BY a.userid
) b ON a.userid = b.userid
where x and y
) c
有了这个,我必须运行原始选择(作为内部选择),对其进行分组和计数(以获取计数),然后将其加入到原始选择中,这非常低效并且成倍地增加了运行时间。
为了效率,我想通过引用结果集来统计每个用户在原始结果中出现的次数。我需要为每个用户保留不同的截止日期,所以我不能简单地按用户 ID 分组。
理想情况下应该是这样的:
| user | due_date | services | counts |
|------|------------|----------|--------|
| 77 | 2019-03-10 | 4 | 1 |
| 81 | 2019-03-05 | 23 | 1 |
| 99 | 2019-03-10 | 97 | 1 |
| 455 | 2019-03-13 | 9 | 1 |
| 478 | 2019-03-10 | 18 | 1 |
| 491 | 2019-03-03 | 1 | 2 |
| 491 | 2019-03-10 | 143 | 2 |
| 541 | 2019-03-02 | 2 | 2 |
| 541 | 2019-03-10 | 68 | 2 |
| 575 | 2019-03-02 | 46 | 1 |
感谢您的帮助!
【问题讨论】:
标签: mysql sql join group-by count