跨越多行的SQL条件

时间:2018-12-17 18:33:14

标签: sql postgresql

我正在基于PostgreSQL数据库的订购系统上工作,因此我有一个OrderLines表,其形式如下:

order_id     int
product_id   int
quantity     int

每个订购的产品在此表中都由一行组成。

我正在尝试运行以下形式的查询:

  • 对于包含产品A,B和C的每个订单,请给我提供产品C和D的数量
  • 对于每个包含产品A和(B或C)的订单,请给我产品D的数量
  • 对于每个包含产品A和至少2 * B的订单,请给我A,B和C的数量

这里的条件可能具有深层嵌套的子句。 可能有数百万个订单,每个订单有10k +行。 这些条件无法事先知道。如果产品不在订单中,则其数量应返回0。

您对编写具有多行条件(例如这一行)的条件有任何指导吗?

2 个答案:

答案 0 :(得分:1)

您可以使用条件聚合。例如第一个:

  

对于每个包含产品A,B和C的订单,请提供我产品C和D的数量

select order_id,
       sum(quantity) filter (where product_id = C) as c_quantity,
       sum(quantity) filter (where product_id = D) as d_quantity
from orderlines ol
group by order_id
having count(*) filter (where product_id = A) > 0 and
       count(*) filter (where product_id = B) > 0 and
       count(*) filter (where product_id = C) > 0 ;

可以用类似的逻辑来处理其他问题,只需更改having条件或sum()

答案 1 :(得分:1)

我想,如果您汇总CTE中所有订单的每个零件的数量,就像这样:

UPDATE ks.tbl SET c = c + [1,2,3] WHERE k = 0

(附带说明-您说的product_id是整数,但列出的值是文本-我认为这里有一个合理的解释,但我并未试图调和)

您可以以此为基础回答以下三个问题:

对于每个包含产品A,B和C的订单,请提供我产品C和D的数量

with summary as (
  select
    order_id,
    sum (case when product_id = 'A' then quantity else 0 end) as a,
    sum (case when product_id = 'B' then quantity else 0 end) as b,
    sum (case when product_id = 'C' then quantity else 0 end) as c,
    sum (case when product_id = 'D' then quantity else 0 end) as d
  from table
  where quantity != 0
  group by order_id
)

对于每个包含产品A和(B或C)的订单,请给我提供产品D的数量

select order_id, c, d
from summary
where a > 0 and b > 0 and c > 0

对于每个包含产品A和至少2 * B的订单,请给我A,B和C的数量

select order_id, d
from summary
where a > 0 and (b > 0 or c > 0)

如果您要运行很多这样的场景,尤其是要处理的数据量,我也将“摘要”包装在实例化视图中。

如果示例是名义性的,并且实际上有数百个或更多的项目编号,那么我将跳过CTE /视图,并使用相关的方案来构建每个案例。