0

假设我有下表users

id name
1  John
2  Mike
3  Max

和表posts

id author_id date       title
1  1         2014-12-12 Post 2
2  1         2014-12-10 Post 1
3  2         2014-10-01 Lorem ipsum
...and so on

我想要一个包含以下数据的查询:

  • 用户名

  • 上周用户发帖数

  • 上个月用户发帖数

我可以为每个单独的用户执行此操作(在以下示例中使用 id 1):

SELECT
  `name`,
  (SELECT COUNT(*) FROM `posts`
   WHERE
     `author` = 1 AND
     UNIX_TIMESTAMP()-UNIX_TIMESTAMP(`date`) < 7*24*3600) AS `posts7`,
  (SELECT COUNT(*) FROM `posts`
   WHERE
     `author` = 1 AND
     UNIX_TIMESTAMP()-UNIX_TIMESTAMP(`date`) < 30*24*3600) AS `posts30`
FROM `users`
WHERE `id` = 1

如果我可以在内部和外部 SELECT 之间交换数据,我怀疑 MySQL 将允许在一个查询中为所有用户执行此操作。我可能用错了词,但我真的希望这里的人能理解我的需求,我会得到一些帮助。

4

3 回答 3

1

当然,聚合非嵌套查询是解决问题的方法,尽管 Benni 和 xQbert 都编写了无界查询——虽然满足了目标,但效率非常低。考虑(改编自本尼的回答):

SELECT `name`
, SUM(IF(
   `date` between DATE(NOW()-INTERVAL 7 DAY) and now() 
   , 1
   , 0) as posts7
, SUM(IF(
   p.author_id IS NULL 
   , 0
   , 1) as posts30
FROM `users` as u
LEFT JOIN posts as p
ON u.id = p.author_id
AND p.date > NOW()-INTERVAL 30 DAY
GROUP BY name

请注意,不使用转换为 UNIX 时间戳允许数据库使用索引(如果可用)来解析查询。

但是,在某些情况下,使用嵌套查询更有效/更合适。因此,尽管这不是解决问题的最佳方法:

SELECT
`name`
, (SELECT COUNT(*) 
   FROM `posts` AS p7
   WHERE p7.author = users.id 
   AND p7.`date` > NOW() - INTERVAL 7 DAY) AS `posts7`
, (SELECT COUNT(*) 
   FROM `posts` AS p30
   WHERE p30.author = users.id 
   AND p30.`date` > NOW() - INTERVAL 30 DAY) AS `posts30`
FROM `users` 
WHERE `id` = 1
于 2014-12-16T19:38:41.440 回答
1

这不是最终的 SQL,但为您提供了 jist...

Select name, sum(case when datewithin7 then 1 else 0 end) as posts7, 
             sum(case when datewithin30 then 1 else 0 end) as posts30
from name
left join posts on name.id = posts.nameid
GROUP BY name.

请注意,您需要分组依据。但我没有时间把案例陈述放在一起......

于 2014-12-16T18:55:23.553 回答
1

尝试这样的事情

  SELECT
    `name`,
    sum(IF(`date` between DATE(NOW()-INTERVAL 7 DAY) and now() , 1, 0) as posts7,
    sum(IF(`date` between DATE(NOW()-INTERVAL 30 DAY) and now() , 1, 0) as posts30
  FROM
    `users` as u, posts as p
  WHERE
    u.id = p.author_id
  GROUP BY
    1
于 2014-12-16T18:55:24.303 回答