为什么当一个连接字段丢失时,hive中的完全外部连接会产生奇怪的结果?

x3naxklr  于 2021-06-02  发布在  Hadoop
关注(0)|答案(2)|浏览(488)

我正在比较sql引擎之间的行为。oracle的行为与我期望的sql引擎完全外部联接的行为相同:

甲骨文

CREATE TABLE sql_test_a 
( 
    ID         VARCHAR2(4000 BYTE), 
    FIRST_NAME VARCHAR2(200 BYTE), 
    LAST_NAME  VARCHAR2(200 BYTE) 
); 

CREATE TABLE sql_test_b 
( 
    NUM         VARCHAR2(4000 BYTE), 
    FIRST_NAME VARCHAR2(200 BYTE), 
    LAST_NAME  VARCHAR2(200 BYTE) 
); 

INSERT INTO sql_test_a (ID, FIRST_NAME, LAST_NAME) VALUES ('1', 'John', 'Snow'); 

INSERT INTO sql_test_a (ID, FIRST_NAME, LAST_NAME) VALUES ('2', 'Mike', 'Tyson'); 

INSERT INTO sql_test_b (NUM, FIRST_NAME, LAST_NAME) VALUES ('20', 'Mike', 'Tyson');

当我执行以下命令时,它会给出预期的结果。结果表包含两行,其中一行包含 NULL 对于 NUM 因为桌上没有约翰·斯诺 sql_test_b .

SELECT A.FIRST_NAME, A.LAST_NAME, A.ID, B.NUM
FROM
SQL_TEST_A A
FULL OUTER JOIN
SQL_TEST_B B
ON 
A.FIRST_NAME = B.FIRST_NAME 
AND
A.LAST_NAME = B.LAST_NAME;

您可以在此处测试sql脚本:http://sqltest.net/

Hive

但是,在hive中,如果要尝试相同的操作,则完整的外部联接将导致一个包含两行的表。应该是“john snow”行的行包含 NULL 对于first\u name、last\u name和num字段 1 是为 ID ,但仅此而已。
为什么在 hive 里有这么奇怪的行为?这是虫子吗?或者我遗漏了什么…因为oracle11g似乎处理得更好。谢谢。

fiei3ece

fiei3ece1#

我无法模拟@candic3报告的结果
我使用了下面的语句以及与问题中相同的“select”查询。

CREATE TABLE IF NOT EXISTS sql_test_a (ID String, FIRST_NAME String, LAST_NAME  String) COMMENT 'sql_test_a'
ROW FORMAT DELIMITED
FIELDS TERMINATED BY '\t'
LINES TERMINATED BY '\n'
STORED AS TEXTFILE;

CREATE TABLE IF NOT EXISTS sql_test_b (NUM String, FIRST_NAME String, LAST_NAME  String) COMMENT 'sql_test_b'
ROW FORMAT DELIMITED
FIELDS TERMINATED BY '\t'
LINES TERMINATED BY '\n'
STORED AS TEXTFILE;

INSERT INTO sql_test_a VALUES ('1', 'John', 'Snow');
INSERT INTO sql_test_a VALUES ('2', 'Mike', 'Tyson');
INSERT INTO sql_test_b VALUES ('20', 'Mike', 'Tyson');

SELECT A.FIRST_NAME, A.LAST_NAME, A.ID, B.NUM
FROM
SQL_TEST_A A
FULL OUTER JOIN
SQL_TEST_B B
ON 
A.FIRST_NAME = B.FIRST_NAME 
AND
A.LAST_NAME = B.LAST_NAME;

请查看附件中的结果。
但是,selectquery会返回null,这是由于未注意到的小错误,例如ddl和实际数据(例如,来自平面文件)之间的数据类型不匹配,或者ddl中提到的分隔符和实际数据中的分隔符不匹配。

83qze16e

83qze16e2#

我认为“(”后面的条件与传统的sql略有不同。

SELECT A.FIRST_NAME, A.LAST_NAME, A.ID, B.NUM
                 FROM
                  SQL_TEST_A A
                     FULL OUTER JOIN
               SQL_TEST_B B ON 
             (A.FIRST_NAME = B.FIRST_NAME AND A.LAST_NAME = B.LAST_NAME);

相关问题