简体   繁体   English

检查日期是否介于其他表的两个日期之间

[英]Check if a date lies between two dates from other table

I have two tables as follow:我有两个表如下:

subscriptions:订阅:

user_id
started_at
ended_at

The subscription table contains historical membership for all the users.订阅表包含所有用户的历史成员资格。 Users who never had subscriptions will not be included in this table.从未订阅过的用户不会包含在此表中。 A user with X historical subscriptions will have X records in the table.具有 X 个历史订阅的用户在表中将有 X 条记录。 For a user's most recent subscription, the col ended_at will be null if the membership is currently active.对于用户最近的订阅,如果成员资格当前处于活动状态,则 colended_at 将为 null。

transactions:交易:

transaction_id (PK)
user_id
started_at
amount

This table tracks, for each historical transaction, the initiation time as well as amount along with user_id.该表跟踪每个历史交易的启动时间以及金额以及 user_id。

How can we know if the corresponding user has active gold membership at the time of making the transaction?我们如何知道交易时对应的用户是否有活跃的金卡会员?

The output should look like something like. output 应该看起来像这样。

transaction_id
user_membership_active (bool)

How can we check if a date from table1 lies between two dates from another table?我们如何检查 table1 中的日期是否位于另一个表中的两个日期之间? Any help is appreciated.任何帮助表示赞赏。

Are you expecting something like this?你期待这样的事情吗?

SELECT transaction_id,
       CASE
         WHEN ended_at IS NULL THEN 'True'
         ELSE 'False'
       END user_membership_active
FROM   transactions t1
       INNER JOIN subscriptions t2
               ON t1.user_id = t2.user_id
                  AND t1.started_at BETWEEN t2.started_at AND
                                            ISNULL(t2.ended_at, GETDATE())

Based on what you want to display, I'm assuming you would still insert a record in transactions table, regardless of whether there exists an active membership or not.根据您要显示的内容,我假设您仍会在事务表中插入一条记录,无论是否存在活动成员。

If you want to do this check after transaction record is inserted -如果您想在插入交易记录后进行此检查 -

Select t.transaction_id,
case when t.started_at >= s.started_at 
and t.started_at < NVL(s.ended_at, SYSDATE())
then 'Y'  -- using Y/N for your boolean output
else 'N'
end as user_membership_active
from transactions t 
inner join subscriptions s on t.user_id = s.user_id

If I understand correctly, you just want a flag.如果我理解正确,您只需要一个标志。 One method uses exists :一种方法使用exists

select t.*
       (exists (select 1
                from subscriptions s
                where s.user_id = t.user_id and
                      s.started_at <= t.started_at and
                      (s.ended_at > t.started_at or s.ended_at is null
                      )
               )
       ) as user_membership_active
from transactions t;

For performance, you want an index on subscriptions(user_id, started_at, ended_at) .为了提高性能,您需要一个关于subscriptions(user_id, started_at, ended_at)

Note: If a person has multiple concurrent subscriptions, this does not multiply the number of rows in the result set.注意:如果一个人有多个并发订阅,这不会乘以结果集中的行数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM