[英]How can I connect a subquery without filters to a query with filters?
I have a query similar to the simplified one below.我有一个类似于下面简化的查询。
SELECT
Users.ID,
Registrations.Timestamp
FROM
Users,
Registrations
WHERE
Users.ID = Registrations.UserID AND
Registrations.Date >= '2020-02-27'
ORDER BY
Users.ID,
Registrations.Timestamp;
I want to calculate a third column named Type
with the values entry
and departure
like the following desired result:我想计算名为
Type
的第三列,其值为entry
和departure
,如下所示:
ID | Timestamp | Type
----+---------------------|----------
1 | 2020-02-27 05:43:24 | entry
1 | 2020-02-27 13:48:47 | departure
1 | 2020-02-28 05:44:38 | entry
1 | 2020-02-28 13:50:11 | departure
2 | 2020-02-27 13:44:41 | entry
2 | 2020-02-27 21:47:54 | departure
2 | 2020-02-28 13:40:16 | entry
2 | 2020-02-28 21:52:57 | departure
3 | 2020-02-27 05:46:20 | departure
3 | 2020-02-28 21:44:05 | entry
3 | 2020-02-28 05:47:18 | departure
The way it calculates it is by counting the amount of registrations up to that one (without the Date
filter).它的计算方式是计算注册数量到那个数量(没有
Date
过滤器)。 If the resulting count number is odd then consider it an entry
else if it's even a departure
.如果结果计数为奇数,则将其视为
entry
否则如果它是偶数departure
。
In the example the user number 3 starts as departure
because even though it is the first registration (odd number), without the Date
filter it's an even number.在示例中,用户编号 3 以
departure
开始,因为即使它是第一次注册(奇数),如果没有Date
过滤器,它也是偶数。
I have tried using a subquery but can't figure out how to count only up to the Timestamp
, not all of them.我试过使用子查询,但不知道如何只计算到
Timestamp
,而不是全部。
SELECT
Users.ID,
Registrations.Timestamp,
CASE WHEN
(
SELECT
COUNT(Registrations.Timestamp)
FROM
Registrations
WHERE
Registrations.UserID = OuterUsers.ID AND
Registrations.Timestamp <= OuterRegistrations.Timestamp
) % 2 = 0 THEN
'departure'
ELSE
'entry'
END AS Type
FROM
Users,
Registrations
WHERE
Users.ID = Registrations.Timestamp.UserID AND
Registrations.Date >= '2020-02-27'
ORDER BY
Users.ID,
Registrations.Timestamp;
This sort of problem is likely not unique but I can't figure out even one solution to it from searching through some similar questions.这类问题可能不是唯一的,但我无法通过搜索一些类似的问题找出一种解决方案。
Use row_number()
first and then filter.首先使用
row_number()
然后过滤。 Also use to learn proper,explicit, standard , readable JOIN
syntax:也用于学习正确的、明确的、标准的、可读的
JOIN
语法:
Select u.*, r.*,
(case when seqnum % 2 = 1 then 'entry' else 'departure' end) as type
FROM users u JOIN
(SELECT r.*,
ROW_NUMBER() OVER (PARTITION BY UserId ORDER BY Date) as seqnum
FROM Registrations r
) r
ON u.ID = r.Timestamp.UserID
WHERE r.Date >= '2020-02-27'
ORDER BY u.ID, r.Timestamp;
Why don't you add a rank/row number ordered by timestamp and use these values to determine departure and entry instead为什么不添加按时间戳排序的排名/行号并使用这些值来确定出发和进入
Select *, case when row_num % 2 = 0 then 'departure' else 'entry' end as type
FROM
(SELECT
Users.ID,
row_number() over (partition by ID order by timestamp) as row_num
FROM
Users,
Registrations
WHERE
Users.ID = Registrations.Timestamp.UserID AND
Registrations.Date >= '2020-02-27'
ORDER BY
Users.ID,
Registrations.Timestamp) a;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.