SELECT *
FROM hc
LEFT OUTER JOIN n
ON hc.JoinHack=n.JoinHack AND (n.`col1` IS NULL OR n.`col1`=hc.`col1`);
我在Drill中运行上述查询时遇到问题。似乎Drill不喜欢外部连接和条件中的OR的组合。
如果我进行内连接,对虚拟列进行相等性检查的解决方法足以消除该错误(在我的情况下为JoinHack
)。使用外连接是不够的。
在查询之前运行以下内容也无济于事:
alter session set `planner.enable_nljoin_for_scalar_only` = false;
此问题的解决方案或解决方法是什么?
答案 0 :(得分:2)
您可以尝试COALESCE
:
SELECT *
FROM hc
LEFT OUTER JOIN n
ON hc.JoinHack=n.JoinHack
AND COALESCE(n.`col1`,hc.`col1`)=hc.`col1`;
或者使用UNION
:
SELECT *
FROM hc
LEFT OUTER JOIN n
ON hc.JoinHack=n.JoinHack
AND n.`col1`=hc.`col1`
UNION
SELECT *
FROM hc
LEFT OUTER JOIN n
ON hc.JoinHack=n.JoinHack
AND n.`col1` IS NULL;
答案 1 :(得分:1)
使用派生表。
select * from
(
SELECT *
FROM hc
LEFT OUTER JOIN n
ON hc.JoinHack=n.JoinHack
) derivedTable
where n.`col1` IS NULL OR n.`col1`=hc.`col1`
这是一般的想法。按原样查询将抛出错误,因为子查询外部不存在n和hc。你可以自己解决这个问题。
答案 2 :(得分:1)
这是非常棘手的逻辑。我认为它通常相当于:
SELECT *
FROM hc INNER JOIN
n
ON hc.JoinHack = n.JoinHack AND n.`col1` IS NULL
UNION ALL
SELECT *
FROM hc INNER JOIN
n
ON hc.JoinHack = n.JoinHack AND n.`col1` = hc.`col1`
UNION ALL
SELECT *
FROM hc LEFT JOIN
n
ON hc.JoinHack = n.JoinHack AND n.`col1` = hc.`col1`
WHERE n.JoinHack IS NULL;
答案 3 :(得分:0)
Drill接受查询的键是分离LEFT OUTER JOIN和包含OR的条件。所以LEFT OUTER JOIN使用子查询来执行INNER JOIN,条件包含OR或者你想要的复杂逻辑。
SELECT *
FROM hc
LEFT OUTER JOIN
(
SELECT
hc.id,
n.*
FROM hc
JOIN n
ON hc.JoinHack=n.JoinHack
AND (n.`col1` IS NULL OR n.`col1`=hc.`col1`)
) m
ON hc.id=m.id;