【问题标题】:Hive SQL - select all rows containing a value; where one of the rows matches a specific valueHive SQL - 选择所有包含值的行;其中一行与特定值匹配
【发布时间】:2017-07-17 13:43:17
【问题描述】:

我有一个这样的 Hive 表 -

Name     ..... Page
Sid ...........Login
Sid ...........Buy 
Nancy ......Home
Nancy ......Register
Nancy ......Buy

我想提取其中一个名称具有 Page=login 的名称的所有行。因此,它会为 name=Sid 提取两行,但不会为 name=Nancy 提取行。

我试过了——

select * from table where name in (select name from table where page='login');

但是,我得到了错误 -

Error while compiling statement: FAILED: SemanticException [Error 10249]: Line 1:142 Unsupported SubQuery Expression ''login'': SubQuery expression refers to Outer query expressions only.

有人可以帮忙吗?这个查询看起来很简单。谢谢

【问题讨论】:

  • 你的错误很奇怪。你能提供样本数据和期望的结果吗?
  • 嗨,真实数据恐怕是 NDA。
  • Sid and Nancy?我在这里约会自己吗?

标签: sql hive


【解决方案1】:

以下查询适用于任何支持 ANSI SQL 的地方:

SELECT t1.*
FROM yourTable t1
INNER JOIN
(
    SELECT Name
    FROM yourTable
    GROUP BY Name
    HAVING SUM(CASE WHEN Page = 'login' THEN 1 ELSE 0 END) > 0
) t2
    ON t1.Name = t2.Name

基本策略是对每个名字进行聚合,统计login作为页面出现的次数,然后只保留符合条件的名字。

【讨论】:

  • 谢谢你,恐怕当我用真实的表名代替你的代码时我不会得到任何结果;我无法分享真实数据,因为它处于 NDA 之下。我会再玩这个。
  • @BobbyKing 单独测试子查询,看看它是否返回正确的匹配名称。如果即使这样也不起作用,那么我的方法可能不适用于 Hive SQL。
【解决方案2】:

您可以使用窗口函数来做到这一点:

select t.*
from (select t.*,
             count(case when page = 'login' then 1 else 0 end) over (partition by name) as numlogins
      from t
     ) t
where numlogins > 0;

【讨论】:

    【解决方案3】:
    猜你喜欢
    • 1970-01-01
    • 2016-10-12
    • 2014-05-15
    • 2021-11-21
    • 2021-12-11
    • 1970-01-01
    • 2021-09-15
    • 2014-03-05
    相关资源
    最近更新 更多