【问题标题】:left outer join results become bigger on hive左外连接结果在 hive 上变大
【发布时间】:2021-01-12 06:05:06
【问题描述】:

所有,我想从这个查询中得到可靠的结果:

SELECT ..

FROM
(
SELECT 
 CO_CODE,
REP.cua cua,
PRD.PRODUCT_DESC, 
REGEXP_EXTRACT(B.rfbbn,'^(?:[^*]*\\*){2}([^*]*)',1) cllt,
NVL(CCY_bbce,0) bbce, 
B.TYPE, 
A.conn_keyy

FROM 
(
SELECT conn_keyy , ext_date FROM 
(tablee.aa) A
)aaxyz 
WHERE flag = 'Y'
)A

LEFT OUTER JOIN 
tablee.B
ON A.conn_keyy = B.conn_keyy

LEFT OUTER JOIN (SELECT DISTINCT * FROM tablee.cc) CPLCUR
ON CPLCUR.conn_keyy = A.conn_keyy
AND CPLCUR.cllt = REGEXP_EXTRACT(B.rfbbn,'^(?:[^*]*\\*){2}([^*]*)',1)
AND CPLCUR.dtdt = '1999' 

LEFT OUTER JOIN (SELECT DISTINCT * FROM tablee.dd) CPLBAL
ON CPLBAL.conn_keyy = A.conn_keyy
AND CPLBAL.SEQUENCE = CPLCUR.SEQUENCE
AND CPLBAL.dtdt = '1999' 

LEFT OUTER JOIN (SELECT DISTINCT * FROM tablee.ee) CPLCCY
ON CPLCCY.conn_keyy = A.conn_keyy
AND CPLCCY.SEQUENCE = CPLCUR.SEQUENCE
AND CPLCCY.dtdt = '1999' 

LEFT OUTER JOIN (SELECT DISTINCT * FROM tablee.ff) CPLMOV
ON CPLMOV.conn_keyy = A.conn_keyy
AND CPLMOV.SEQUENCE = CPLCUR.SEQUENCE
AND CPLMOV.dtdt = '1999' 

LEFT OUTER JOIN
 (tablee.REP)REP 
ON REP.relino = B.lnido

LEFT OUTER JOIN tablee.P PRD
ON PRD.PRODUCT_CODE = REGEXP_EXTRACT(A.conn_keyy,'[.]([^.]+)',1)
AND PRD.dtdt = '1999'

WHERE B.lnido LIKE 'PLCONS1%'
) rrvv;

fyi,A 的选择计数 (*) 约为 60,000

我只是想知道为什么我的查询结果变成了 15 亿.. 我错过了什么?我操作左外连接时出了什么问题?

【问题讨论】:

  • 首先,表 B 上的 LEFT JOIN 并不是真正的 LEFT JOIN,但它是 INNER JOIN,因为您在 WHERE 子句中使用了B.lnido LIKE 'PLCONS1%'。接下来,尝试逐个删除 LEFT JOIN 以检查行数是否减少,因为似乎有一对多的关系在结果记录中相乘。
  • 如果我可能会问,它应该在这样的情况下产生多少列?仅供参考,当我从 B 中选择计数 (*) 时,结果约为 350,000。或者我应该指定不同的列? sqlandhadoop.com/hive-distinct
  • 请按照我在我的第一条评论here 中所说的去做,包括将您的代码剪切和简化为第一个不返回您期望的子表达式并说出您期望的内容以及您期望的原因,并说明理由根据权威文档。 left join minimal reproducible example 否则,您只是要求编写另一本带有定制教程的手册,而没有任何关于您的误解所在的线索。 PS请合理格式化您的代码。 PS你的问题被固定后将是一个很容易找到的常见问题解答。

标签: sql join left-join hiveql


【解决方案1】:

Join 可以复制行如果连接键在第二个表中不是唯一的,并且如果连接键在两个表中都不是唯一的,则会产生更多的重复。

例如:

with 

A as (
select 1 key, 'one' name
union all
select 1 key, 'two' name
),

B as (
select 1 key, 'one' name
union all
select 1 key, 'two' name
)

select *
  from A left join B on A.key=B.key

结果有四行,每个表只包含两个:

a.key   a.name  b.key   b.name
1       one     1       one
1       one     1       two
1       two     1       one
1       two     1       two

如何找到重复的键:

select B.conn_keyy, count(*) cnt 
  from tablee.B
group by B.conn_keyy
 having count(*)>1
order by cnt desc limit 100;

检查您要加入的每个表并决定您可以执行的操作:应用过滤、区分或添加更多连接键以进行连接(一对一或零)或(多对一或零

【讨论】:

  • 抱歉,已编辑。 A 查询包含唯一值,它给出 0 个结果。另一方面,给出了许多结果(不是唯一的 conn_keyy)。我认为我没有适当地执行左外连接。你怎么看? cwiki.apache.org/confluence/plugins/servlet/…
  • @thecardcaptor 也许你应该使用额外的加入密钥。 (复杂的连接键)。也许您需要在加入之前删除重复项。这通常与 Hive 文档或 Joins 语法无关。检查连接键。如果它不是唯一的,第一次加入后会重复,第二次加入会产生更多的重复。如果连接键不是唯一的 - 连接会产生重复,这是正常的连接行为。只需研究您的数据并选择正确的连接键(它可以是复杂的键,由许多列组成)
  • 我已经尝试使用组合 coalesce (),当我尝试加入基于 A..stackoverflow.com/questions/65705636/… 的其他 conn_key 时它停止了@
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-10-01
相关资源
最近更新 更多