【问题标题】:Get all Date of month along with data from table获取所有日期以及表中的数据
【发布时间】:2017-10-29 05:50:24
【问题描述】:

我有两张桌子user_profiletracked_searchuser_profile 表包含用户详细信息,tracked_search 跟踪每个用户进行的搜索。

每当用户进行搜索时,此搜索条目都会进入tracked_search 表。如果没有针对特定日期搜索任何内容,则不会在 tracked_search 中添加任何内容。

我需要开发一个报告,我需要在其中显示一个月的所有日子有多少用户进行了搜索。

例如:

CREATE TABLE tracked_search (
    id int NOT NULL AUTO_INCREMENT PRIMARY KEY,
    created DATE,
    user_id int NOT NULL
);

INSERT INTO tracked_search(created, user_id) VALUES
('2017-10-01', 1000),
('2017-10-01', 1000),
('2017-10-01', 2000),
('2017-10-01', 3000),
('2017-10-01', 4000),
('2017-10-04', 1000),
('2017-10-04', 2000),
('2017-10-04', 2000),
('2017-10-04', 2000),
('2017-10-04', 2000),
('2017-10-04', 3000),
('2017-10-31', 1000),
('2017-10-31', 2000),
('2017-10-31', 3000),
('2017-10-31', 4000),
('2017-10-31', 5000);

期望的输出:

Date       user_count 
2017-10-01    4
2017-10-02    0
2017-10-03    0
2017-10-04    3
2017-10-05    0
...
2017-10-30    0
2017-10-31    5

我写了以下查询

SELECT ts.created , count( distinct ts.user_id) FROM tracked_search ts, user_profile u
 WHERE ts.created>=(CURDATE()-INTERVAL 1 MONTH) AND u.id = ts.user_id
 group by ts.created;

但我明白了

Date       user_count 
2017-10-01    4
2017-10-04    3
2017-10-31    5

如果特定日期没有条目,我需要打印所有天的值,它应该为零。

我正在使用 MySQL。

【问题讨论】:

  • 数据显示问题通常最好在应用程序代码中解决,如果有的话。
  • 但我需要每天发送数据。在java中,我将不得不检查哪些日期不存在,然后将那些日期为零的日期插入列表中。这个过程是可以避免的。

标签: mysql


【解决方案1】:

顺便说一句,你不需要在 user_profile 上加入。

如果您有一个带有相关日期的dates 表,这很容易:

SELECT dates.day AS `Date`, COUNT(DISTINCT ts.user_id) AS user_count
FROM dates
LEFT OUTER JOIN tracked_search AS ts
    ON ts.created = dates.day
GROUP BY dates.day;

由于您可能没有dates 表并且可能不想创建和维护一个表,您可以使用其中一种解决方案来即时生成日期列表。例如Get a list of dates between two datesHow to get list of dates between two dates in mysql select query

SELECT dates.day AS `Date`, COUNT(DISTINCT ts.user_id) AS user_count
FROM (
    SELECT ADDDATE('1970-01-01', t4.i * 10000 + t3.i * 1000 + t2.i * 100 + t1.i * 10 + t0.i) AS day
    FROM (SELECT 0 AS i UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) AS t0,
         (SELECT 0 AS i UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) AS t1,
         (SELECT 0 AS i UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) AS t2,
         (SELECT 0 AS i UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) AS t3,
         (SELECT 0 AS i UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) AS t4
) AS dates
LEFT OUTER JOIN tracked_search AS ts
    ON ts.created = dates.day
WHERE dates.day >= '2017-10-01'
AND dates.day < '2017-11-01'
GROUP BY dates.day;

【讨论】:

  • 嗨 Wodin 感谢您的回复。如果我想按周分组相同的东西怎么办。要求发生了变化。我在以下链接 stackoverflow.com/questions/47013616/… 上创建了一个新问题
  • @Suyash 我已经根据上述答案回答了您的其他问题。
【解决方案2】:

你需要写没有AND u.id = ts.user_id

SELECT ts.created , count( distinct ts.user_id) FROM tracked_search ts, user_profile u
 WHERE ts.created>=(CURDATE()-INTERVAL 1 MONTH) 
 group by ts.created;

【讨论】:

  • 如果数据库中不存在日期条目,则结果应为 0。请考虑我提供的示例。不过感谢您的帮助,
【解决方案3】:

我能够使用以下逻辑解决此问题,希望对某人有所帮助

select 
t1.attempt_date,
coalesce(SUM(t1.attempt_count+t2.attempt_count), 0) AS attempt_count
from
(
  select DATE_FORMAT(a.Date,'%Y/%m/%d') as attempt_date,
  '0' as  attempt_count
  from (
    select curdate() - INTERVAL (a.a + (10 * b.a) + (100 * c.a)) DAY as Date
    from (select 0 as a union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) as a
    cross join (select 0 as a union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) as b
    cross join (select 0 as a union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) as c
  ) a
  where a.Date BETWEEN NOW() - INTERVAL 1 MONTH AND NOW()
)t1
left join
(
  SELECT DATE_FORMAT(ts.created,'%Y/%m/%d') AS attempt_date, 
  count( distinct ts.user_id) AS attempt_count
  FROM tracked_search ts, user_profile u
  WHERE ts.user_id = u.id and
  DATE_SUB(ts.created, INTERVAL 1 DAY) > DATE_SUB(DATE(NOW()), INTERVAL 1 MONTH) 
  GROUP BY DAY(ts.created) DESC
)t2
on t2.attempt_date = t1.attempt_date
group by DAY(t1.attempt_date)
order by t1.attempt_date desc;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-11-02
    • 2014-02-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-17
    • 1970-01-01
    相关资源
    最近更新 更多