KSQL左连接仅显示流字段不显示表字段,是否为预期结果?
咱们先明确:这绝对不是左连接的预期输出。左连接的核心逻辑就是保留左流(这里是DEAL_STREAM)的所有符合过滤条件的行,同时如果右表(EXPENSE_TABLE)有匹配ON子句条件的记录,就会返回对应的表字段;没有匹配的话,表字段会显示为NULL。如果你的结果里完全看不到TE.EXPENSE_DESC,或者它全程为空,大概率是下面几个原因导致的:
1. 右表根本没有匹配的记录
最常见的情况是:DEAL_STREAM里满足EXPENSE_CODE LIKE '%NL%' AND BRANCH_CODE LIKE '%AM%'的行,它们的EXPENSE_CODE在EXPENSE_TABLE中找不到对应的值。你可以单独跑个查询验证右表的匹配情况:
SELECT EXPENSE_CODE, EXPENSE_DESC FROM EXPENSE_TABLE WHERE EXPENSE_CODE LIKE '%NL%';
如果这个查询返回空结果,那左连接后TE.EXPENSE_DESC自然全是NULL——如果你的客户端默认不显示NULL值的字段,就会看起来像表字段完全没输出。
2. 连接键的数据类型不匹配
KSQL对连接键的数据类型要求严格一致。比如如果DEAL_STREAM.EXPENSE_CODE是STRING类型,而EXPENSE_TABLE.EXPENSE_CODE是INT类型,哪怕值看起来一样(比如字符串"123"和整数123),KSQL也会判定为不匹配,导致右表字段无法关联上。
你可以用DESCRIBE命令确认两个结构的字段类型:
DESCRIBE DEAL_STREAM; DESCRIBE EXPENSE_TABLE;
重点核对EXPENSE_CODE的类型是否完全一致。
3. 过滤条件的位置(虽非当前问题,但值得注意)
如果是左连接,过滤右表的条件必须放在ON子句里,而不是WHERE子句里——如果把右表的过滤条件放WHERE,会把左连接变成内连接的效果(自动过滤掉右表无匹配的行)。不过你的WHERE里只有左流的条件,所以这个问题暂时不影响,但以后要过滤右表的话一定要注意。
快速验证步骤
你可以先简化查询,去掉WHERE条件,看看能不能拿到TE.EXPENSE_DESC的非NULL值:
SELECT TD.EXPENSE_CODE, TD.BRANCH_CODE, TE.EXPENSE_DESC FROM DEAL_STREAM TD LEFT JOIN EXPENSE_TABLE TE ON TD.EXPENSE_CODE = TE.EXPENSE_CODE LIMIT 10;
如果这个简化查询能看到非空的TE.EXPENSE_DESC,那说明原来的WHERE条件过滤掉了所有有右表匹配的左流行,剩下的都是无匹配的行,所以显示NULL。
内容的提问来源于stack exchange,提问作者Zamir Arif

