我有两张表user_profile
和tracked_search
。 user_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。
答案 0 :(得分: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 dates或How 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;
答案 1 :(得分:0)
您需要在没有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;
答案 2 :(得分:0)
我能够使用以下逻辑来解决这个问题,希望它可以帮助某人
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;