我在 oracle sql 中的左连接没有返回左表的每个元素

Posted

技术标签:

【中文标题】我在 oracle sql 中的左连接没有返回左表的每个元素【英文标题】:My left join in oracle sql is not returning every element of the left table 【发布时间】:2020-08-14 03:05:49 【问题描述】:

我正在尝试获取表 B_ARTICULOS 上的所有元素并进行一些计算加入其他表(B_ARTICULOS 的某些元素不存在),我知道我必须为此使用左连接但是我不知道我做错了什么。

通过这个查询,我没有得到每个B_ARTICULOS,只有那些列在其他表中的那些

SELECT a.id, a.nombre,
  CASE WHEN a.id IN dc.id_articulo THEN dc.cantidad ELSE 0 END CANTIDAD_COMPRAS,
  CASE WHEN a.id IN dc.id_articulo THEN dc.cantidad * a.costo ELSE 0 END MONTO_COMPRAS, 
  CASE WHEN a.id IN dv.id_articulo THEN dv.cantidad ELSE 0 END CANTIDAD_VENTAS, 
  CASE WHEN a.id IN dv.id_articulo THEN dv.cantidad * a.precio ELSE 0 END MONTO_VENTAS 
FROM B_ARTICULOS a
  LEFT JOIN B_DETALLE_COMPRAS dc ON a.id = dc.id_articulo
  JOIN B_COMPRAS c ON  dc.id_compra = c.id
  JOIN B_DETALLE_VENTAS dv ON dv.id_articulo = a.id
  JOIN B_VENTAS v ON v.id = dv.id_venta
WHERE a.id IS NOT NULL;

【问题讨论】:

【参考方案1】:

我在这里看到的唯一解释是,除了第二个 B_DETALLE_COMPRAS 表之外,您应该加入其他一些表。假设您将在任何地方使用左连接:

SELECT
    a.id,
    a.nombre,
    CASE WHEN a.id IN dc.id_articulo THEN dc.cantidad ELSE 0 END CANTIDAD_COMPRAS,
    CASE WHEN a.id IN dc.id_articulo THEN dc.cantidad * a.costo ELSE 0 END MONTO_COMPRAS, 
    CASE WHEN a.id IN dv.id_articulo THEN dv.cantidad ELSE 0 END CANTIDAD_VENTAS, 
    CASE WHEN a.id IN dv.id_articulo THEN dv.cantidad * a.precio ELSE 0 END MONTO_VENTAS 
FROM B_ARTICULOS a
LEFT JOIN B_DETALLE_COMPRAS dc ON a.id = dc.id_articulo
LEFT JOIN B_COMPRAS c ON dc.id_compra = c.id
LEFT JOIN B_DETALLE_VENTAS dv ON dv.id_articulo = a.id
LEFT JOIN B_VENTAS v ON v.id = dv.id_venta
WHERE a.id IS NOT NULL;

【讨论】:

【参考方案2】:

对于其他表格,您也必须使用left join,如下所示:

...
FROM B_ARTICULOS a
  LEFT JOIN B_DETALLE_COMPRAS dc ON a.id = dc.id_articulo
  LEFT JOIN B_COMPRAS c ON  dc.id_compra = c.id
  LEFT JOIN B_DETALLE_VENTAS dv ON dv.id_articulo = a.id
  LEFT JOIN B_VENTAS v ON v.id = dv.id_venta
...

就个人而言,我为所有将与主表连接的相关表进行子查询。我将这些表分组,然后将它们加入主表,如下所示:

...
FROM B_ARTICULOS a
  LEFT JOIN (
    SELECT dc.*
    FROM B_DETALLE_COMPRAS dc
      JOIN B_COMPRAS c ON dc.id_compra = c.id
  ) dc on a.id = dc.id_articulo
  LEFT JOIN (
    SELECT dv.*
    FROM B_DETALLE_VENTAS dv
      JOIN B_VENTAS v ON v.id = dv.id_venta
  ) dv ON dv.id_articulo = a.id
...

【讨论】:

以上是关于我在 oracle sql 中的左连接没有返回左表的每个元素的主要内容,如果未能解决你的问题,请参考以下文章

左外连接和右外连接的区别

左连接

Oracle_SQL 连接和子查询

SQL中的左连接与右连接,内连接有啥区别

SQL数据库的多表查询

Access SQL 中的联接语句