Postgres-嵌套联接表上的条件不起作用

时间:2019-04-16 13:26:42

标签: sql ruby-on-rails postgresql

我有3张桌子: order_items,invoice_items和发票

在order_items模型中:

has_many :invoice_items

P.S order_item可能有或没有与之关联的发票项目

发票模型:

has_many :invoice_items

InvoiceItem模型

belongs_to :order_item
belongs_to :invoice

order_items表中有booked_quantitycancelled_quantity字段

发票表中有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。

1 个答案:

答案 0 :(得分:0)

对于那些被困于此问题/类似问题的人..主意是,只有那些发票项目应在取消发票状态的地方加入。如果我们有两个单独的join语句,那么即使取消了发票状态,发票项目也将被合并。因此,基本上,发票项目的合并应该有一个内部查询,以仅过滤出相关的发票项目。

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

.select{
    width: 100%;
    height: 45px;
    position: relative;
}
.select::after{
    content: '\f0d7';
    position: absolute;
    top: 0px;
    right: 10px;
    font-family: 'Font Awesome 5 Free';
    font-weight: 900;
    color: #0b660b;
    font-size: 45px;
    z-index: 2;

}
#dropdown{
    -webkit-appearance: button;
       -moz-appearance: button;
            appearance: button;
            height: 45px;
            width: 100%;
        outline: none;
        border: none;
        border-bottom: 2px solid #0b660b;
        font-size: 20px;
        background-color: #0b660b23;
        box-sizing: border-box;
        padding-left: 10px;
        padding-right: 10px;
}