【问题标题】:Postgres - Where condition on nested joins table not workingPostgres - 嵌套连接表的条件不起作用
【发布时间】:2019-04-16 13:26:42
【问题描述】:

我有 3 张桌子: order_items、invoice_items 和 invoices

在 order_items 模型中:

has_many :invoice_items

P.S an order_item 可能有也可能没有任何与之关联的发票项目

在发票模型中:

has_many :invoice_items

InvoiceItem 模型中

belongs_to :order_item
belongs_to :invoice

order_items 表中有 booked_quantitycancelled_quantity 字段

invoices 表中有 state 字段。 state 可以取消或批准

invoice_items 表中有 quantity 字段。

当满足以下条件时,订单项目被视为可开票:

(booked_quantity - cancelled_quantity - SUM(invoice_items.quantity 关联发票未取消)) > 0

我正在尝试使用单个 sql 查询获取所有可开票的订单项目。以下是我尝试过的两种解决方案:

解决方案 1:

SELECT * FROM order_items
       LEFT OUTER JOIN invoice_items ON invoice_items.order_item_id = order_items.id
       INNER JOIN invoices ON invoices.id = invoice_items.invoice_id
       WHERE invoices.state != 'cancelled'
       GROUP BY order_items.id
       HAVING ((booked_quantity - cancelled_quantity - COALESCE(SUM(invoice_items.quantity))) > 0)
       ORDER BY order_items.id ASC

解决方案 2:

(
  WITH ii_ord_items AS
  (
    SELECT invoice_items.order_item_id, COALESCE(SUM(invoice_items.quantity), 0) AS uncancelled_invoiced_quantity from order_items
    LEFT OUTER JOIN invoice_items ON invoice_items.order_item_id = order_items.id
    INNER JOIN invoices ON invoices.id = invoice_items.invoice_id
    WHERE invoices.state != 'cancelled'
    GROUP BY invoice_items.order_item_id
  )
  SELECT order_items.* FROM order_items
  LEFT OUTER JOIN ii_oitems ON order_items.id = ii_oitems.order_item_id
  WHERE ( ii_ord_items.uncancelled_invoiced_quantity < (order_items.booked_quantity - order_items.cancelled_quantity))
) AS order_items

当发票未处于取消状态时,它们都可以正常工作。但是如果发票被取消,他们都会给出不正确的结果。他们似乎也在考虑取消的发票数量。所以我想 where 条件存在一些问题,但我无法弄清楚究竟是什么问题。任何帮助,将不胜感激。提前致谢!!

样本数据:

order_items 表

id      booked_quantity   cancelled_quantity
1          10                    2

发票表

id      state
1       cancelled

invoice_items 表

id      invoice_id    order_item_id     quantity
1           1              1               8

预期结果:如果我尝试获取可以生成 invoice_items 的所有订单项目,则应包括 ID 为 1 的 order_item 以及当前已取消发票。如果发票状态不是“已取消”,则结果中不应出现 ID 为 1 的 order_item。

【问题讨论】:

  • InvoiceItem,你有belongs_to :invoice_item。是不是打错字了?
  • 是的。会解决这个问题。
  • 样本数据和期望的结果将帮助我理解这个问题。
  • @GordonLinoff 我已更新问题以包括样本数据和结果。好心检查。谢谢

标签: sql ruby-on-rails postgresql


【解决方案1】:

对于那些遇到此/类似问题的人......我们的想法是只有那些发票项目应该在发票状态被取消的地方加入。如果我们有两个单独的连接语句,那么即使发票状态被取消,发票项目也会被连接。所以基本上,发票项目的加入应该有一个内部查询来过滤掉只关注的发票项目。

这是我实施的最终解决方案:

 SELECT DISTINCT oi.*
  FROM order_items oi
  LEFT OUTER JOIN
         (SELECT ii.* from invoice_items ii
         INNER JOIN invoices inv
         ON inv.id = ii.invoice_id AND inv.state != 'cancelled') uncancelled_ii
         ON uncancelled_ii.order_item_id = oi.id
  GROUP BY oi.id
  HAVING (booked_quantity - cancelled_quantity - COALESCE(SUM(uncancelled_ii.quantity), 0)) > 0
  ORDER BY oi.id ASC

【讨论】:

    猜你喜欢
    • 2020-04-16
    • 2021-06-26
    • 2013-02-19
    • 2014-06-26
    • 1970-01-01
    • 1970-01-01
    • 2015-05-22
    • 2012-05-07
    相关资源
    最近更新 更多