钻取:由于笛卡尔连接或不等式连接,可能无法计划此查询

时间:2018-01-16 15:27:55

标签: sql outer-join apache-drill

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;

此问题的解决方案或解决方法是什么?

4 个答案:

答案 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;