2

我有一个查询,它返回每天注册的用户总数。问题是如果一天没有人注册它不会返回任何值,它只是跳过它。我宁愿它返回零

这是我到目前为止的查询

SELECT count(*) total FROM users WHERE created_at < NOW() AND created_at > 
DATE_SUB(NOW(), INTERVAL 7 DAY) AND owner_id = ? GROUP BY DAY(created_at) 
ORDER BY created_at DESC

编辑

我对数据进行了分组,这样我每天都会得到一个计数——至于日期范围,我想要前 7 天注册的用户总数

4

4 回答 4

1

主题“内联构建您的 7 天日历”的变体:

SELECT D, count(created_at) AS total FROM
(SELECT DATE_SUB(NOW(), INTERVAL D DAY) AS D
    FROM
    (SELECT 0 as D
     UNION SELECT 1
     UNION SELECT 2
     UNION SELECT 3
     UNION SELECT 4
     UNION SELECT 5
     UNION SELECT 6
     ) AS D
) AS D
LEFT JOIN users ON date(created_at) = date(D)
WHERE owner_id = ? or  owner_id is null
GROUP BY D 
ORDER BY D DESC

我手头没有你的表格结构,所以可能需要调整。按照同样的思路,你会看到我使用NOW()了作为参考日期。但这很容易调整。反正就是精神...

查看现场演示http://sqlfiddle.com/#!2/ab5cf/11

于 2013-08-15T19:32:03.037 回答
0

如果您有一张可以容纳您所有时间的表格,您可以从那里对您的用户表格进行左连接。

SELECT SUM(CASE WHEN U.Id IS NOT NULL THEN 1 ELSE 0 END)
FROM DimDate D
LEFT JOIN Users U ON CONVERT(DATE,U.Created_at) = D.DateValue
WHERE YourCriteria
GROUP BY YourGroupBy
于 2013-08-15T18:58:33.667 回答
0

有点啰嗦,但我认为这会奏效......

SELECT count(users.created_at) total FROM
  (SELECT DATE_SUB(CURDATE(),INTERVAL 6 DAY) as cdate UNION ALL
   SELECT DATE_SUB(CURDATE(),INTERVAL 5 DAY) UNION ALL
   SELECT DATE_SUB(CURDATE(),INTERVAL 4 DAY) UNION ALL
   SELECT DATE_SUB(CURDATE(),INTERVAL 3 DAY) UNION ALL
   SELECT DATE_SUB(CURDATE(),INTERVAL 2 DAY) UNION ALL
   SELECT DATE_SUB(CURDATE(),INTERVAL 1 DAY) UNION ALL
   SELECT CURDATE()) t1 left join users
ON date(created_at)=t1.cdate 
WHERE owner_id = ? or owner_id is null
GROUP BY t1.cdate 
ORDER BY t1.cdate DESC

它与您的查询略有不同,因为它适用于日期而不是您的查询正在执行的日期时间。根据您的描述,我假设您的意思是使用一整天,因此使用了日期。

于 2013-08-15T19:14:32.347 回答
0

棘手的一点是您按数据中的日期字段进行分组,其中可能有“漏洞”,因此会丢失该日期的记录。

解决此问题的一种方法是在表格中填写过去 10 年和未来 100 年左右的所有日期,并将其(外部)加入您的数据。然后,您肯定每天(或每周或其他任何时间)都会有一个记录。

我只需要为 MS SqlServer 执行此操作,因此如何填写日期表(或者您可以动态填写)由其他人来回答。

于 2013-08-15T19:25:38.353 回答