【问题标题】:Error while compiling statement: FAILED: SemanticException [Error 10002]编译语句时出错:失败:SemanticException [错误 10002]
【发布时间】:2017-05-02 06:28:47
【问题描述】:
select d.order_type from migu_td_aaa_order_log_d d where  exists(select 1 
from migu_user r where r.user_id = '156210106' and r.user_num = 
d.serv_number) and d.product_id in ('2028594290','2028596512','2028597138' ) 
order by d.opr_time desc limit 1 

上面的sql为什么失败,说明: 失败:SemanticException [错误 10002]:第 4:11 行无效列引用“opr_time”

但下面的工作:

select temp.order_type from (
select d.* from migu_td_aaa_order_log_d d where  exists(select 1 from 
migu_user r where r.user_id = '156210106' and r.user_num = d.serv_number) 
and d.product_id in ('2028594290','2028596512','2028597138' ) order by 
d.opr_time desc limit 1) temp;

这个也很好用,而且比第二个效率高:

select d.* from migu_td_aaa_order_log_d d where  exists(select 1 from 
migu_user r where r.user_id = '156210106' and r.user_num = d.serv_number) 
and d.product_id in ('2028594290','2028596512','2028597138' ) 
order by d.opr_time desc limit 1

我只需要获取 order_type 字段,所以即使第二个有效,但它花费的时间要多得多。 谁能帮我? 非常感谢!

【问题讨论】:

    标签: mysql sql hadoop hive


    【解决方案1】:

    您的第一个查询不起作用,因为在第一个 select 语句中,您只得到一列 (d.order_type),但您试图按另一列 (d.opr_time) 排序,而您尚未将其包含在你的select 声明

    select d.order_type from ...
    ...
    order by d.opr_time desc limit 1
    

    请注意,如果您将 d.opr_time 列添加到您的第一个查询中,它将起作用:

    select d.order_type, d.opr_time from ...
    ...
    order by d.opr_time desc limit 1
    

    您的第二个查询有效,因为在子查询中,您选择了d (d.*) 的所有列,因此当您按opr_time 排序时,该列存在。 (第三个查询也一样)。

    select temp.order_type from (
    select d.* ... order by d.opr_time ...
    

    已编辑:

    根据Hive documentation:

    使用group by子句时,select语句只能包含 group by 子句中包含的列。当然,你可以有 选择语句中的许多聚合函数(例如计数)为 好吧。

    所以,这个查询:

    select d.order_type, d.opr_time from ...
    ...
    order by d.opr_time desc limit 1
    

    也不应该工作,因为 select 子句有一个额外的列 (d.order_type) 不包含在 group by 子句中。

    我希望这会有所帮助。

    附: This answer关于 SQL 执行顺序可能有用。

    【讨论】:

    • 感谢您的回答!但是在mysql中,不包含在select语句中的情况下按列排序就可以了,所以我没有考虑这个原因..
    • @RickGeng 是的,这在 mysql 中是可能的,但是因为该数据库扩展了group by 的使用:(“MySQL 扩展了 GROUP BY 的使用,以便您可以在 SELECT 中使用非聚合列或计算未出现在 GROUP BY 子句中的列表。")(stackoverflow.com/a/1023349/2026277)。在 Hive 中似乎并非如此。
    • 感谢您的帮助,很抱歉撤消接受... Dudu Markovitz 的回答恰好解决了我的真正问题。我希望你不会介意。我是这个社区的新手,我不不太懂规矩。
    • 完全不用说对不起。另一个答案肯定更准确,并且准确地回答了您的需要,因此它应该是公认的答案。欢迎来到 StackOverflow :-)
    • 我真的希望我可以选择多个答案..感谢您的考虑和耐心的回答
    【解决方案2】:

    1.

    Hive 目前有 order by 限制。
    此问题的当前状态是PATCH AVAILABLE。

    请参阅 -
    “无法按未选择的列排序”
    https://issues.apache.org/jira/browse/HIVE-15160

    2.

    您可能想熟悉LEFT SEMI JOIN,它是EXISTS 的更简洁语法 https://cwiki.apache.org/confluence/display/Hive/LanguageManual+Joins#LanguageManualJoins-JoinSyntax

    3.

    在struct / named_struct 上使用min / max 可以代替order by ... asc / desc 和limit 1

    这里有一个替代解决方案:

    select      max(named_struct('opr_time',d.opr_time,'order_type',d.order_type)).order_type
    
    from                        migu_td_aaa_order_log_d d 
                
                left semi join  migu_user               r 
                
                on              r.user_num  =  
                                d.serv_number 
                            
                            and r.user_id   = '156210106' 
    
    where       d.product_id in ('2028594290','2028596512','2028597138') 
    ;
    

    附言

    您确实需要考虑将 ID(user_id、product_id)视为数字而不是字符串。

    【讨论】:

    • 非常感谢你的慷慨帮助,这个函数named_struct解决了我的问题。起初,我决定使用临时表。在你的帮助下,我可以用这个代替。 select temp.* from ( select d.serv_number,r.user_id,max(named_struct('opr_time',d.opr_time,'order_type',d.order_type)).order_type from migu_td_aaa_order_log_d d , migu_user r where d.serv_number = r.user_num and r.user_id in ('156210106','156547688') and d.product_id in ('2028596512','2028597138') group by d.serv_number,r.user_id )temp where temp.order_type = '1'
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-09-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多