【问题标题】:Joining 2 subsets of same table with different conditions连接具有不同条件的同一张表的 2 个子集
【发布时间】: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

标签: hiveql impala


【解决方案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