bounty将在2天后过期。回答此问题可获得+50声望奖励。wejoey希望引起更多人关注此问题。
我有每个产品及其skuid的库存标签。一个产品可以多1个Skuid。
product_skus_inventories表:
ProductID SkuID Inventory_Label
123 a1 InStock
123 a2 OutOfStock
123 a3 NULL
我想更新下表,这是一个总结:
product_summary
- product_id
- inventory_label (values can be InSock, OutOfStock or Partial)
其逻辑如下:
1.如果给定productID的所有SkuID为“InStock”或NULL,则为“InStock”。
1.如果任何SkuId具有“InStock”,而其他SkuId具有不同的值,则为“Partial”。
1.否则为“缺货”。
在更新查询中是否可以使用这种类型的逻辑?
4条答案
按热度按时间tquggr8v1#
收集每个产品的标签组合,并指定每个组合
case
的总结:demo这可以用作更新源,如演示的最后所示。
将其设置为
view
或materialized view
,将其用作insert into...on conflict do update
或merge
的源(也在演示中),可能会更有意义。jjhzyzn02#
Alternatives到我的initial answer,在@Mike Organek的建议下尝试其他聚合函数:
count(distinct inventory_label)
组合:demobit
s,使用编码:demo10
)对于InStock
,01
)(对于OutOfStock
),bit_or()
得到11
(十进制3),或者10
(2)只得到InStock
我更喜欢
array_agg(distinct inventory_label)
,因为它的可读性。这些都很简单,但那个也是自我评论。尽管如此,count()
比filter
短,bit_or()
是faster。hlswsv353#
您可以创建一个表的视图,该视图生成状态,然后在需要值时可以轻松查询。如果您需要运行UPDATE来具体化库存标签,则可以使用
JOIN LATERAL
中的SELECT来获取要插入的给定product_id的状态。状态逻辑如下:
1.检查给定product_id的行数是否与筛选出
out_of_stock
后的行数匹配。1.因为我们知道至少有1个
out_of_stock
存在于这个product_id中,因为前面的子句不匹配,所以我们只需要检查是否存在至少1个in_stock
或NULL
。1.否则,
out_of_stock
。xoshrz7s4#
基本查询
带原表定义
不要对所有行进行计数或聚合。基本上,您正在寻找一个布尔结果。这两个聚合函数恰好符合您的任务描述 * 完全 *:
bool_and()
包含case “1."bool_or()
覆盖案例 “2."创建一个快速而简单的查询:
fiddle
值得注意的是,源代码中的
'OutOfStock'
和null
实际上是等效的,并且可以互换。使用
boolean
更好product_skus_inventories.inventory_label
可以是“in”,“out”或null
。这是一个**boolean
**的数量。使用合适的上级数据类型。仅占用1个字节,使所有内容更短,更简单,更快。要转换表(触发具有排他锁的完整表重写),请执行以下操作:
然后运行一次
VACUUM ANALYZE product_skus_inventories
。现在,查询变得更加简单和快速:
fiddle
“更新”汇总表
适当的操作是UPSERT,实际上是Postgres中的.
INSERT ... ON CONFLICT ... DO UPDATE ...
。假定此表定义:
一个三个三个一个
fiddle
请注意添加的
WHERE
子句,它跳过了所有不会改变状态的更新,通常会使查询成本降低很多。