可能是子查询而不是联接

时间:2019-02-21 14:38:09

标签: sql postgresql

下面的这个大查询返回了2860条记录及其正确的编号。我越来越。事情是,我需要添加到此查询发票行中,并进行与sale_order_lines "sum(l.price_subtotal / COALESCE(cr.rate, 1.0)) AS price_subtotal"相同的操作。我需要获取发票行的price_subtotal的总和。

所以我首先想到的是像这样联接表。

JOIN sale_order_invoice_rel so_inv_rel on (so_inv_rel.order_id = s.id )
JOIN account_invoice inv on (inv.id = so_inv_rel.invoice_id and inv.state in ('open','paid'))
JOIN account_invoice_line ail on (inv.id = ail.invoice_id)

然后

sum(ail.price_subtotal / COALESCE(cr.rate, 1.0)) as price_subtotal

但是在第一个JOIN行数之后,我选择的是更改,即使我完成了连接,这些数字也基本相距5x2860。因此,可能我需要进行一些子查询,但是在这一点上,我不知道如何寻求帮助。

WITH currency_rate AS (
         SELECT r.currency_id,
            COALESCE(r.company_id, c.id) AS company_id,
            r.rate,
            r.name AS date_start,
            ( SELECT r2.name
                   FROM res_currency_rate r2
                  WHERE r2.name > r.name AND r2.currency_id = r.currency_id AND (r2.company_id IS NULL OR r2.company_id = c.id)
                  ORDER BY r2.name
                 LIMIT 1) AS date_end
           FROM res_currency_rate r
             JOIN res_company c ON r.company_id IS NULL OR r.company_id = c.id
        )
 SELECT min(l.id) AS id,
    l.product_id,
    l.color_id,
    l.product_size_id,
    t.uom_id AS product_uom,
    sum(l.product_uom_qty / u.factor * u2.factor) AS product_uom_qty,
    sum(l.qty_delivered / u.factor * u2.factor) AS qty_delivered,
    sum(l.qty_invoiced / u.factor * u2.factor) AS qty_invoiced,
    sum(l.qty_to_invoice / u.factor * u2.factor) AS qty_to_invoice,
    sum(l.price_total / COALESCE(cr.rate, 1.0)) AS price_total,
    l.price_unit / COALESCE(cr3.rate, 1.0) AS price_total_by_cmp_curr,
    sum(l.price_subtotal / COALESCE(cr.rate, 1.0)) AS price_subtotal,
    count(*) AS nbr,
    s.date_order AS date,
    s.state,
    s.partner_id,
    s.user_id,
    s.company_id,
    date_part('epoch'::text, avg(date_trunc('day'::text, s.date_order) - date_trunc('day'::text, s.create_date))) / (24 * 60 * 60)::numeric(16,2)::double precision AS delay,
    t.categ_id,
    s.pricelist_id,
    s.project_id AS analytic_account_id,
    s.team_id,
    p.product_tmpl_id,
    partner.country_id,
    partner.commercial_partner_id
   FROM sale_order_line l
     JOIN sale_order s ON l.order_id = s.id
     JOIN res_partner partner ON s.partner_id = partner.id
     LEFT JOIN product_product p ON l.product_id = p.id
     LEFT JOIN product_template t ON p.product_tmpl_id = t.id
     LEFT JOIN product_uom u ON u.id = l.product_uom
     LEFT JOIN product_uom u2 ON u2.id = t.uom_id
     LEFT JOIN res_company rc ON rc.id = s.company_id
     LEFT JOIN product_pricelist pp ON s.pricelist_id = pp.id
     LEFT JOIN currency_rate cr ON cr.currency_id = pp.currency_id AND cr.company_id = s.company_id AND cr.date_start <= COALESCE(s.date_order::timestamp with time zone, now()) AND (cr.date_end IS NULL OR cr.date_end > COALESCE(s.date_order::timestamp with time zone, now()))
     LEFT JOIN currency_rate cr3 ON cr.currency_id = rc.currency_id AND cr.company_id = s.company_id AND cr.date_start <= COALESCE(s.date_order::timestamp with time zone, now()) AND (cr.date_end IS NULL OR cr.date_end > COALESCE(s.date_order::timestamp with time zone, now()))
  GROUP BY l.product_id, t.uom_id, t.categ_id, s.date_order, s.partner_id, s.user_id, s.state, s.company_id, s.pricelist_id, s.project_id, s.team_id, l.color_id, cr3.rate, l.price_unit, l.product_size_id, p.product_tmpl_id, partner.country_id, partner.commercial_partner_id;

1 个答案:

答案 0 :(得分:2)

您可以将可能在子查询中的部分添加到with语句中,您必须避免增加行数,如下所示:

WITH currency_rate AS (
         SELECT r.currency_id,
            COALESCE(r.company_id, c.id) AS company_id,
            r.rate,
            r.name AS date_start,
            ( SELECT r2.name
                   FROM res_currency_rate r2
                  WHERE r2.name > r.name AND r2.currency_id = r.currency_id AND (r2.company_id IS NULL OR r2.company_id = c.id)
                  ORDER BY r2.name
                 LIMIT 1) AS date_end
           FROM res_currency_rate r
             JOIN res_company c ON r.company_id IS NULL OR r.company_id = c.id
        )
 , order_line_subtotal AS(
            SELECT so_inv_rel.order_id, sum(ail.price_subtotal) as price_subtotal
            FROM sale_order_invoice_rel so_inv_rel
            JOIN account_invoice inv on (inv.id = so_inv_rel.invoice_id and inv.state in ('open','paid'))
            JOIN account_invoice_line ail on (inv.id = ail.invoice_id)
            GROUP BY so_inv_rel.order_id )
 SELECT min(l.id) AS id,
 ....

从那里开始,应该直接添加到查询中而不增加行数(因为从联接中,您已经在聚合/分组依据之前为每个订单都有一行。