【问题标题】:Get all rows with a matching field in a different row in the same table获取同一表中不同行中具有匹配字段的所有行
【发布时间】:2013-08-07 13:38:53
【问题描述】:

假设我有一张这样的桌子:

|id|userID|email         |website    |
--------------------------------------
|1 |user1 |user1@test.com|website.com|
|2 |user2 |user2@test.com|website.com|
|3 |user3 |user3@test.com|website.com|
|4 |user1 |user1@test.com|foo.com    |
|5 |user2 |user2@test.com|foo.com    |

我想获取 website='website.com' 的所有行,并在 website='foo.com' 有一个匹配的用户 ID 的相应行

因此,在这种情况下,它将返回第 1 行和第 2 行。

有什么想法吗?

【问题讨论】:

    标签: sql hive impala


    【解决方案1】:

    这是一种方法:

    select t.*
    from t
    where t.website = 'website.com' and
          exists (select 1 from t t2 where t2.userId = t.userId and t2.website = 'foo.com');
    

    编辑:

    您也可以将其表示为连接:

    select distinct t.*
    from t join
         t2
         on t2.userId = t.userId and
            t.website = 'website.com' and
            t2.website = 'foo.com';
    

    如果你知道没有重复,那么你可以删除distinct

    【讨论】:

    • 据我所知,Hive 和 Impale 都不支持 exists 子句。这是完全有效的 sql,但在这种情况下不起作用。
    【解决方案2】:

    为了得到用户你可以做

    select userID
    from your_table
    where website in ('website.com', 'foo.com')
    group by userID
    having count(distinct website) = 2
    

    但是如果你需要完整的行然后做

    select * from your_table
    where userID in
    (
       select userID
       from your_table
       where website in ('website.com', 'foo.com')
       group by userID
       having count(distinct website) = 2
    )
    

    【讨论】:

    • 这似乎工作得很好!有什么方法可以从匹配的行中获取所有列,而不仅仅是 userID?
    • @JGibel:是的,这是我回答中的第二个问题。
    • 这似乎适用于标准 SQL,不幸的是 impala 不支持 in 子句中的子查询。我会发布另一个问题来尝试解决这个问题,谢谢!
    • 我做到了,但我遇到了类似的问题。不过我确实找到了解决方法!对于任何查看此内容的人,请在此处查看:stackoverflow.com/questions/10710075/… 谢谢,@juergen d
    • 供参考:正如我的回答中提到的,Hive 中的子查询只允许在 FROM 子句中使用。因此,此答案中的第二个查询是完全有效的 sql,但在 Impala 或 Hive 中不起作用。 cwiki.apache.org/confluence/display/Hive/…
    【解决方案3】:

    Hive 在使用子查询方面有点受限(它们在FROM 子句中使用are only allowed),所以我们必须解决这个问题。好消息是我们不必(太多)担心进行大规模连接,因为,Hadoop。 :-)

    在表中查找匹配行的一种方法是简单地将表连接起来。

    SELECT left.*
    FROM your_table left
    JOIN your_table right
    ON (left.userID = right.userID)
    WHERE left.website = 'website.com'
    AND right.website = 'foo.com';
    

    请注意,我们有同一个表的两个版本,分别称为 leftright,我们正在从 left 检索在 right 中具有相同用户 ID (JOIN) 的匹配行的行条件)但网站是 foo.com(and 子句)。

    希望对您有所帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-01-08
      • 1970-01-01
      • 1970-01-01
      • 2023-01-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-10-05
      相关资源
      最近更新 更多