【问题标题】:Selecting * from Hive Temporary Table Immediately after creating the Temporary Table Not Working在创建临时表后立即从 Hive 临时表中选择 * 不起作用
【发布时间】:2021-06-30 04:27:58
【问题描述】:

我正在尝试创建一些临时表来获取最近的分区,然后内部连接回主表以过滤掉旧分区。为此,我更喜欢使用临时表而不是大量嵌套子查询。我正在使用 SAS 等工具通过 pass-through proc sql 连接到数据库并查询数据。

例子:

proc sql;
CONNECT TO ODBC (USER=XXXXX PASSWORD="XXXXX" DSN="XXXXX");

CREATE TABLE max_partition as SELECT * FROM CONNECTION TO ODBC
(
CREATE TEMPORARY TABLE tmp1 as select MAX(partitiondate) as latestpartitiondate, id FROM tbl1 GROUP BY id;

select * from tmp1
);
quit;

如果我不包含分号,我会通过“选择”得到关于缺少 EOF 的错误,如果我使用分号,我会收到一个错误(如上例所示)。

CLI prepare error: [Hortonworks][Hardy] (80) Syntax or semantic analysis error thrown in server while executing query. Error message
       from server: Error while compiling statement: FAILED: ParseException line 1:148 cannot recognize input near 'id' ';' ')'

我正在尝试在各种工具中使用临时表,例如 SAS 中的 Proc sql 以及 Python 中的 pyodbc。我仍然收到相同的错误。我只是希望能够为该特定 ID 生成一个最大分区表,然后在单个 pass through 语句中完全从该临时表中进行选择。

【问题讨论】:

  • 您是否正确触发 SQL?这似乎是一个语法错误。似乎它不喜欢列id。触发时可以用反引号将 id 列括起来吗?
  • 你能展示你完整的 SQL Pass through 代码吗?
  • 删除了 python 标签,因为这似乎与 python 无关。如果您重新添加 python 标签,请同时添加您的 Python 代码。
  • 去掉括号,它们没有用处:CREATE TEMPORARY TABLE tmp1 as select MAX(partitiondate) as latestpartitiondate, id FROM tbl1 GROUP BY id;
  • @Reeza 更新帖子。

标签: hive sas


【解决方案1】:

正常的方法是先运行先决条件语句,然后运行查询。

EXECUTE BY ODBC
(
  CREATE TEMPORARY TABLE tmp1 as 
  select MAX(partitiondate) as latestpartitiondate
       , id 
  FROM tbl1 
  GROUP BY id
);
CREATE TABLE max_partition as SELECT * FROM CONNECTION TO ODBC
(
  select * from tmp1
);

这不适用于 HIVE 吗?

【讨论】:

    【解决方案2】:

    在 SAS proc sql 中,你不能做你正在做的事情 - 但你也不需要这样做,除非 Hive 与任何其他 ODBC 连接有很大不同。

    proc sql;
    CONNECT TO ODBC (USER=XXXXX PASSWORD="XXXXX" DSN="XXXXX");
    
    CREATE TABLE max_partition as SELECT * FROM CONNECTION TO ODBC
    (
    select MAX(partitiondate) as latestpartitiondate, id FROM tbl1 GROUP BY id;
    );
    quit;
    

    如果您确实需要创建临时表,则必须在 execute ( ) by connection to odbc 中进行,这应该是可能的(我对 SQL Server 做过类似的事情,只要 SAS 和 Hive 实现 ODBC以同样的方式连接应该没问题),然后在下面的语句中执行 select

    【讨论】:

    • 谢谢。我了解上述声明会起作用。但是,如果我需要编写多个 Hive 查询(假设我要加入多个具有不同 MAX(partitiondate) 的表),我将无法在传递到 Hive 的语句中间查询 SAS CREATE TABLE,因为 SAS上面创建的表将存储在我的 SAS 工作库中。例如。我需要一次性运行它以获取并加入与原始表具有不同分区日期的所有表。
    • 然后展示你想做什么,你不能这样做,我们可以帮助你。一般来说,你不能那样做一个序列——你需要分开做。你可以做一个大查询,只是不能在同一个块中创建表。 SELECT * FROM CONNECTION TO ODBC 需要包含一个SELECT
    • SELECT * FROM CONNECTION TO ODBC ( SELECT A,B,C FROM TBL1 LEFT JOIN ( SELECT * FROM TBL2) TBL2 ON TBL1.ID = TBL2.ID LEFT JOIN TBL3 ON TBL1.ID=TBL3.ID 等都可以,你也可以使用with CTE 的leftjoin 注释也可以。
    • 是什么让您认为需要一次性完成,您的临时表会在查询完成后消失吗?
    • @Coldchain9 我认为您可以轻松地在一个查询中完成它 - 使用 CTE 或子查询或连接 - 但实际上您可以采用任何一种方式,就像 Tom 显示的那样制作临时表是可以的他的回答或者我在这个最后提到的,或者使用一个CTE。您不能在一个 select 中完成所有操作,仅此而已。
    【解决方案3】:

    Some drivers may not support multiple sql statements in single session.

    作为一种解决方法,使用在单独会话中加载的永久表(插入覆盖)并在其他会话中重复使用。 Temp teble 与永久 teble 相比没有任何改进,只是它在结束时会自动删除,并且不能在不同的会话中重复使用。

    如果不重用表,FROM 中的 WITH (CTE) 或简单子查询也比临时表运行得更快。 WITH 可以在同一个查询中实现和重复使用多次。

    【讨论】:

    • 传递查询的 SAS 语法需要 () - 但您可能是对的,它不会像他那样支持这两个语句。
    猜你喜欢
    • 2010-10-24
    • 1970-01-01
    • 1970-01-01
    • 2015-10-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多