连接具有不同条件的同一张表的 2 个子集
Posted
技术标签:
【中文标题】连接具有不同条件的同一张表的 2 个子集【英文标题】:Joining 2 subsets of same table with different conditions 【发布时间】:2021-04-02 12:32:18 【问题描述】:ID | Timestamp | type | account |
---|---|---|---|
212 | 2021-01-06 14:47:35 | 019 | ALA058748 |
212 | 2021-01-07 18:34:44 | 021 | API305575 |
212 | 2021-01-07 22:34:48 | 021 | XYZ565656 |
212 | 2021-01-08 00:31:25 | 021 | API305575 |
212 | 2021-01-08 00:31:31 | 021 | API305575 |
212 | 2021-01-08 00:34:44 | 020 | API305575 |
123 | 2021-05-21 03:34:44 | 021 | API305575 |
123 | 2021-05-21 05:34:44 | 019 | API305575 |
123 | 2021-05-21 09:34:44 | 021 | API305575 |
123 | 2021-05-21 03:34:44 | 020 | PQR464646 |
我有一张像上面这样的桌子
我只需要选择那些 -
步骤 1) MINIMUM(Timestamp) 类型 = 021 的 ID --- 说 X
第 2 步)(时间戳),类型 = 020,ID 和帐户与 X 中的相同 --- Say Y
WHERE (Y-X) in minutes > 30
在此示例中 - 将仅选择 ID 212,因为对于 ID 123 ,具有 MIN(Timestamp) 的帐户,其中 type=021 具有类型=020 的帐户
谢谢
【问题讨论】:
我删除了不一致的数据库标签。请仅使用您真正使用的数据库进行标记。 您使用的是哪个 dbms? Hive/Impala SQL 【参考方案1】:架构:
create table t
(
ID int,
Timestamp datetime,
type int,
account varchar(50)
);
insert into t values(212, '2021-01-06 14:47:35', 019, 'ALA058748');
insert into t values(212, '2021-01-07 18:34:44', 021, 'API305575');
insert into t values(212, '2021-01-07 22:34:48', 021, 'XYZ565656');
insert into t values(212, '2021-01-08 00:31:25', 021, 'API305575');
insert into t values(212, '2021-01-08 00:31:31', 021, 'API305575');
insert into t values(212, '2021-01-08 00:34:44', 020, 'API305575');
insert into t values(123, '2021-05-21 03:34:44', 021, 'API305575');
insert into t values(123, '2021-05-21 05:34:44', 019, 'API305575');
insert into t values(123, '2021-05-21 09:34:44', 021, 'API305575');
insert into t values(123, '2021-05-21 03:34:44', 020, 'PQR464646');
mysql 的查询 #1:
select id
from t
group by id
having TIMESTAMPDIFF(minute, min(case when type = '021' then timestamp end),
min(case when type = '020' then timestamp end))>30
SQL Server 的查询 #2:
select id
from t
group by id
having datediff(minute, min(case when type = '021' then timestamp end),
min(case when type = '020' then timestamp end))>30
输出:
id |
---|
212 |
db小提琴here
【讨论】:
【参考方案2】:您可以使用聚合和过滤来做您想做的事。众所周知,日期函数依赖于数据库,因此“30 分钟”逻辑可能在您的数据库中有所不同:
select id, account
from t
group by id, account
having min(timestamp) = min(case when type = '021' then timestamp end) and
min(timestamp) < min(case when type = '020' then timestamp end) + interval '30 minute'
【讨论】:
我也需要考虑帐户,对于需要验证时间差异的两个时间戳应该相同。 @AjinkyaPujari 。 . .如果您对 id/account 组合都需要它,那么只需将它用于group by
。
@GordonLinoff 你能帮我得到两个时间戳值吗? ,我可以弄清楚差异逻辑。我想加入表本身,一个实例与 min(timestamp) where type = 021 和另一个实例的 timestamp where type=020 ,加入基于ID和Account以上是关于连接具有不同条件的同一张表的 2 个子集的主要内容,如果未能解决你的问题,请参考以下文章