【问题标题】:SQL alternative to sub-query in SELECT Item listSQL 替代 SELECT 项目列表中的子查询
【发布时间】:2014-09-25 21:22:53
【问题描述】:

我有运行良好的 RDBMS 表和查询。我已将数据从 RDBMS 卸载到 HIVE 表。要在 HIVE 上运行现有查询,我们首先需要使它们与 HIVE 兼容。

让我们以选择项目列表中的子查询为例。它在语法上有效并且在 RDBMS 系统上运行良好。但它不适用于 HIVE 根据 HIVE manual ,Hive 仅在 FROM 和 WHERE 子句中支持子查询。

示例 1:

SELECT t1.one
    ,(SELECT t2.two 
        FROM TEST2 t2 
        WHERE t1.one=t2.two) t21
    ,(SELECT t3.three 
        FROM TEST3 t3 
        WHERE t1.one=t3.three) t31
FROM TEST1 t1 ;

示例 2:

SELECT a.*
   , CASE
          WHEN EXISTS
                 (SELECT 1
                    FROM tblOrder O
                      INNER JOIN tblProduct P
                              ON O.Product_id = P.Product_id
                   WHERE O.customer_id        = C.customer_id
                     AND P.Product_Type IN (2, 5, 6, 9)
                 )
          THEN 1
          ELSE 0
   END AS My_Custom_Indicator
   FROM tblCustomer C
   INNER JOIN tblOtherStuff S
       ON C.CustomerID = S.CustomerID ;

示例 3:

Select component_location_id, component_type_code,
  ( select clv.LOCATION_VALUE 
  from stg_dev.component_location_values clv 
  where  identifier_code = 'AXLE' 
       and component_location_id = cl.component_location_id ) as AXLE,
  ( select clv.LOCATION_VALUE 
  from stg_dev.component_location_values clv 
  where identifier_code = 'SIDE' 
       and component_location_id = cl.component_location_id ) as SIDE
  from stg_dev.component_locations cl ;

我想知道选择项目列表中子查询的可能替代方案,以使其与 hive 兼容。显然,我将能够以 HIVE 格式转换现有查询。

非常感谢任何帮助和指导!

【问题讨论】:

  • 谢谢大家,我已经添加了更多示例

标签: sql hive


【解决方案1】:

您提供的查询可以转换为带有LEFT JOINs 的简单查询。

SELECT
  t1.one, t2.two AS t21, t3.three AS t31
FROM
  TEST1 t1
  LEFT JOIN TEST2 t2
    ON t1.one = t2.two
  LEFT JOIN TEST3 t3
    ON t1.one = t3.three

由于子查询没有限制,连接将返回相同的数据。 (对于 TEST1 中的每一行,子查询应该只返回一行或不返回一行。)

请注意,您的原始查询无法处理 1..n 个连接。在大多数 DBMS 中,SELECT 列表中的子查询应该只返回一个包含一列和一行或没有行的结果集。

【讨论】:

    【解决方案2】:

    基于HIVE manual:

    SELECT t1.one, t2.two, t3.three 
    FROM TEST1 t1,TEST2 t2, TEST3 t3
    WHERE t1.one=t2.two AND t1.one=t3.three;
    

    【讨论】:

    • 这是一个 INNER JOIN,原始查询中的子查询可能会返回一个空的结果集。您的查询过滤 TEST2 或 TEST3 中没有值的所有值。
    【解决方案3】:
        SELECT t1.one,t2.two,t3.three FROM TEST1 t1 INNER 
       JOIN TEST2 t2 ON t1.one=t2.two INNER JOIN TEST3 t3 
       ON t1.one=t3.three WHERE t1.one=t2.two AND t1.one=t3.three;
    

    【讨论】:

    • 嗨,这可能很好地解决了问题......但如果你能编辑你的答案并提供一些关于它的工作原理和原因的解释会很好: ) 不要忘记 - Stack Overflow 上有很多新手,他们可以从你的专业知识中学到一两件事 - 对你来说显而易见的事情对他们来说可能不是。
    【解决方案4】:
    SELECT t1.one,t2.two as t21,t3.three as t31 FROM TEST1 t1 
    INNER JOIN TEST2 t2 ON t1.one=t2.two
    INNER JOIN TEST3 t3 ON t1.one=t3.three
    

    【讨论】:

    • 嗨,这可能很好地解决了问题......但如果你能编辑你的答案并提供一些关于它的工作原理和原因的解释会很好: ) 不要忘记 - Stack Overflow 上有很多新手,他们可以从你的专业知识中学到一两件事 - 对你来说显而易见的事情对他们来说可能不是。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-23
    • 1970-01-01
    相关资源
    最近更新 更多