【问题标题】:Nested select in hiveQLhiveQL 中的嵌套选择
【发布时间】:2017-05-31 05:40:43
【问题描述】:

在我的一个用例中,我有两个表,即 flow 和 conf。流表包含所有航班数据的列表。它有列creationdate、datafilename、aircraftid。 conf 表包含配置信息。它有 configdate、aircraftid、configurationame 列。为一种飞机类型创建了多个版本的配置。因此,当我们处理数据文件名时,我们需要从流表中识别飞机 ID,并从创建数据文件名之前创建的 conf 表中获取配置。所以,我尝试了这个,

FROM (
SELECT  
F_FILE_CREATION_DATE,    
F_FILE_ARCHIVED_RELATIVE_PATH,   
F_FILE_ARCHIVED_NAME,   
K_AIRCRAFT   
from T_FLOW f )x left join 
(
  select c.config_date, c.aircraft_id, c.configurationfrom t_conf c
) y on y.aircraft_id = x.K_AIRCRAFT 
select    
x.F_FILE_CREATION_DATE,  
x.F_FILE_ARCHIVED_RELATIVE_PATH,   
x.F_FILE_ARCHIVED_NAME,   
x.K_AIRCRAFT,   
y.config_date,
y.aircraft_id,
y.configuration;

这会提取为飞机创建的所有配置,这是显而易见的,因为没有条件检查 conf.config_date 。我试着像这样包含这个条件,

 FROM (
SELECT  
F_FILE_CREATION_DATE,    
F_FILE_ARCHIVED_RELATIVE_PATH,   
F_FILE_ARCHIVED_NAME,   
K_AIRCRAFT   
from T_FLOW f )x join 
(
  select c.config_date, c.aircraft_id, c.FILEFILTER from t_conf c
) y on y.aircraft_id = x.K_AIRCRAFT  where y.config_date < x.f_file_creation_date    
select    
x.F_FILE_CREATION_DATE,  
x.F_FILE_ARCHIVED_RELATIVE_PATH,   
x.F_FILE_ARCHIVED_NAME,   
x.K_AIRCRAFT,   
y.config_date,
y.aircraft_id,
y.filefilter;

这次失败,报错

 required (...)+ loop did not match anything at input 'where' in statement

谁能给我一两个提示我哪里出错了,以及如何解决这个问题?

【问题讨论】:

    标签: hadoop hive hiveql


    【解决方案1】:
    select  f.f_file_creation_date
           ,f.f_file_archived_relative_path   
           ,f.f_file_archived_name
           ,f.k_aircraft
           
           ,c.config_date
           ,c.aircraft_id
           ,c.filefilter
    
    from            t_flow  as f
    
            join   (select  config_date
                           ,aircraft_id
                           ,filefilter
                           
                           ,lead (config_date,1,date '3000-01-01') over 
                            (
                                partition by    aircraft_id
                                order by        config_date  
                            )   as next_config_date                        
                    
                    from    t_conf
                    ) c
            
            on      c.aircraft_id = 
                    f.k_aircraft
    
    where   f.f_file_creation_date  >=  c.config_date 
        and f.f_file_creation_date  <   c.next_config_date   
        
    

    请仔细阅读

    发布问题

    当您发布与数据相关的问题时 -

    1. 提供数据样本:源数据 + 所需结果。
      这将比你给出的任何解释都更清楚。 它还将为进一步讨论提供一个共同背景,并为您和其他人验证给定解决方案的正确性提供了一种方法。
    2. 提供表的大小属性(记录/卷)。
      这对于性能考虑很重要,可能会影响给定的解决方案。

    SQL

    1. Hive 目前不支持除 equijoin 之外的任何 JOIN 条件类型(例如 t1.X = t2.X and t1.Y = t2.Y)。这就是您收到错误的原因。
      如果您正在执行内连接(而不是外连接),则可以将非等连接条件移至 WHERE 子句。
    2. 坚持 ISO SQL 标准。 SQL 子句有一个约定的顺序:SELECT-FROM-WHERE...
      除了深奥的错误消息之外,您不会从深奥的语法中获得任何好处。
    3. 没有任何理由使用子查询来缩小列列表。
      只是为了清楚地说明 - 这样做并没有任何性能提升。更重要的是,如果它能够像您假设的那样工作(但事实并非如此),那么性能会更差,而不是更好。

    【讨论】:

    • 谢谢 .. 我带你的 cmets。
    【解决方案2】:

    我无法重现您的错误。我猜你的查询是有效的。 你用什么版本的 Hive ?我用 hive 2.1.1 测试了这个查询。

    DROP TABLE IF EXISTS t_flow;
    CREATE TABLE IF NOT EXISTS t_flow (
        f_file_creation_date            DATE
        , f_file_archived_relative_path STRING
        , f_file_archived_name          STRING
        , k_aircraft                    STRING
    );
    
    -- Conf table contains configuration information.
    -- It has columns configdate, aircraftid, configurationame
    DROP TABLE IF EXISTS t_conf;
    CREATE TABLE IF NOT EXISTS t_conf (
        config_date   DATE
        , aircraft_id STRING
        , filefilter  STRING
    );
    
    SELECT
        x.f_file_creation_date,
        x.f_file_archived_relative_path,
        x.f_file_archived_name,
        x.k_aircraft,
        y.config_date,
        y.aircraft_id,
        y.filefilter
    FROM
        (SELECT
            f_file_creation_date,
            f_file_archived_relative_path,
            f_file_archived_name,
            k_aircraft
        FROM t_flow f) x
        JOIN
        (SELECT
        c.config_date,
        c.aircraft_id,
        c.filefilter
        FROM t_conf c) y on y.aircraft_id = x.k_aircraft  where y.config_date < x.f_file_creation_date;
    

    【讨论】:

    • 谢谢.. 这将返回在“config_date”之前创建的所有配置。但是,我只需要选择在“creation_date”之前“刚刚”创建的一个。我测试了你的查询。它没有失败,但给出了在“creation_date”之前创建的所有配置的多行。
    • 我建议您也阅读我对 OP 的回答中的 cmets
    猜你喜欢
    • 1970-01-01
    • 2013-03-27
    • 2011-02-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-16
    • 2020-12-07
    • 2019-12-04
    相关资源
    最近更新 更多