Return 结果集中第一次出现 user_id
Return the first occurrence of a user_id from a result set
我有两个表(简化为):
+----------------+
| attendances |
+-----+----------+
| int | user_id |
+-----+----------+
| int | event_id |
+-----+----------+
+-------------------------+
| events |
+------+------------------+
| int | id |
+------+------------------+
| date | performance_date |
+------+------------------+
以及一个简单的查询:
SELECT count(DISTINCT user_id), events.performance_date
FROM attendances
INNER JOIN events
ON event_id = events.id
GROUP BY performance_date
我只想计算每个 user_id
一次,但上面的查询只删除每个 performance_date
中的重复项(允许它们在多个日期重复)。
是否有一个查询可以从整个结果集中删除重复的 user_ids,并且只包括第一次出现的(日期明智的)?我怀疑这不可能。
Input/output 例子:
如果用户在 2010 年 10 月 10 日和 2010 年 10 月 11 日再次参加活动,则结果将是:
1, 2010-10-10
不是:
1, 2010-10-10
1, 2010-10-11
或:
2, 2010-10-10
如果在上面添加了另一个用户,并且他们分别在 2010 年 10 月 10 日和 2010 年 10 月 12 日参加,那么结果将是:
2, 2010-10-10
1, 2020-10-12
正如我所说,这可能是不可能的。实际输出并不严格——只要可以以某种方式得出参加特定表演的人数的唯一数量即可。
数据将用于构建独立用户数量按事件增长的累积图。
如果您想要每个用户的最早日期,您可以使用聚合:
select u.id user_id, min(e.date) first_event_date
from users u
inner join events e on u.event_id = e.id
group by u.id
实际上,您可能正在寻找直方图,即每个最早事件日期的用户数。您可以通过添加另一个聚合级别来完成此操作:
select first_event_date, count(*) no_users
from (
select min(e.date) first_event_date
from users u
inner join events e on u.event_id = e.id
group by u.id
) t
group by first_event_date
如果您想统计每个事件的所有新用户,您可以使用以下查询:
SELECT Count(u.user_id),
e.performance_date
FROM attendances u
INNER JOIN `events` e
ON u.event_id = e.id
WHERE NOT EXISTS(SELECT u1.user_id
FROM attendances u1
INNER JOIN `events` e1
ON u1.event_id = e1.id
WHERE u1.user_id = u.user_id
AND e1.performance_date < e.performance_date)
GROUP BY performance_date
ORDER BY performance_date
我用下面的设置测试了它:
CREATE TABLE attendances
(
user_id INT,
event_id INT
);
CREATE TABLE `events`
(
id INT,
performance_date DATE
);
INSERT INTO attendances
(user_id,
event_id)
VALUES ( 1, 1),
( 1, 2),
( 2, 1),
( 2, 2),
( 3, 1),
( 4, 2);
INSERT INTO `events`
(id,
performance_date)
VALUES ( 1, '2020-07-24'),
( 2, '2020-07-25');
然后结果是
3 2020-07-24
1 2020-07-25
我有两个表(简化为):
+----------------+
| attendances |
+-----+----------+
| int | user_id |
+-----+----------+
| int | event_id |
+-----+----------+
+-------------------------+
| events |
+------+------------------+
| int | id |
+------+------------------+
| date | performance_date |
+------+------------------+
以及一个简单的查询:
SELECT count(DISTINCT user_id), events.performance_date
FROM attendances
INNER JOIN events
ON event_id = events.id
GROUP BY performance_date
我只想计算每个 user_id
一次,但上面的查询只删除每个 performance_date
中的重复项(允许它们在多个日期重复)。
是否有一个查询可以从整个结果集中删除重复的 user_ids,并且只包括第一次出现的(日期明智的)?我怀疑这不可能。
Input/output 例子:
如果用户在 2010 年 10 月 10 日和 2010 年 10 月 11 日再次参加活动,则结果将是:
1, 2010-10-10
不是:
1, 2010-10-10
1, 2010-10-11
或:
2, 2010-10-10
如果在上面添加了另一个用户,并且他们分别在 2010 年 10 月 10 日和 2010 年 10 月 12 日参加,那么结果将是:
2, 2010-10-10
1, 2020-10-12
正如我所说,这可能是不可能的。实际输出并不严格——只要可以以某种方式得出参加特定表演的人数的唯一数量即可。
数据将用于构建独立用户数量按事件增长的累积图。
如果您想要每个用户的最早日期,您可以使用聚合:
select u.id user_id, min(e.date) first_event_date
from users u
inner join events e on u.event_id = e.id
group by u.id
实际上,您可能正在寻找直方图,即每个最早事件日期的用户数。您可以通过添加另一个聚合级别来完成此操作:
select first_event_date, count(*) no_users
from (
select min(e.date) first_event_date
from users u
inner join events e on u.event_id = e.id
group by u.id
) t
group by first_event_date
如果您想统计每个事件的所有新用户,您可以使用以下查询:
SELECT Count(u.user_id),
e.performance_date
FROM attendances u
INNER JOIN `events` e
ON u.event_id = e.id
WHERE NOT EXISTS(SELECT u1.user_id
FROM attendances u1
INNER JOIN `events` e1
ON u1.event_id = e1.id
WHERE u1.user_id = u.user_id
AND e1.performance_date < e.performance_date)
GROUP BY performance_date
ORDER BY performance_date
我用下面的设置测试了它:
CREATE TABLE attendances
(
user_id INT,
event_id INT
);
CREATE TABLE `events`
(
id INT,
performance_date DATE
);
INSERT INTO attendances
(user_id,
event_id)
VALUES ( 1, 1),
( 1, 2),
( 2, 1),
( 2, 2),
( 3, 1),
( 4, 2);
INSERT INTO `events`
(id,
performance_date)
VALUES ( 1, '2020-07-24'),
( 2, '2020-07-25');
然后结果是
3 2020-07-24
1 2020-07-25