我试图弄清楚如何在查询中的其他列为true时将一列设置为true。
我有两个表叫做产品和家庭。一个家庭可以有很多产品,一个产品可以有一个主要产品。
当我执行select时,我应该:
- 所有没有系列的产品
- 所有具有系列的产品
- 所有产品有一个家庭,是一个主要产品(如果该产品是主要产品,我不需要从这个家庭恢复其他产品,只有主要产品)
我的问题是a有一个名为product_launch的列,当产品单独出现时很容易恢复。所以我试图设置一个在我的查询中返回以下规则的主产品的字段:如果这个系列的任何产品都有一个标志product_launch为true,我应该将main product product_launch列设置为true,即使main product为false。
在这个fiddle中,我有一个我正在尝试的例子。
我已经尝试过使用any、over/window和aggregate函数,但没有任何东西能够达到我的目标。
在这个例子的最后,我的目标是返回例如PlayStation 3的product_launch为true,因为它是一个主要产品,而PlayStation 5在同一个家族中具有product_launch true。在其他情况下,它已经工作了,因为它单独带来了。
在这个例子中,我有以下规则:
- 百事可乐和可口可乐应该回来,因为他们没有家人。
- MacBook 2015和MacBook 2018属于家庭(MacBook),但其中任何一个都是主要产品,所以我应该选择接收它们。
- 家庭控制台唯一可以返回的产品是playstation3,因为它是家庭控制台的主要产品。但它需要将标志product_launch更改为true,因为在家庭控制台中(控制台)有一个产品(PlayStation 5)有这个标志真.如果我有一些产品在家庭有标志产品_launch as true即使main product的product_launch标志为false,我也应该返回带有此标志的main product。
希望有人能帮助我知道如何在PostgreSQL中实现这个目标。谢谢!
3条答案
按热度按时间7rfyedvj1#
我不确定我是否完全理解你想要的。我添加了一个“playstation 4”行,它不是main_product,所以它的
product_launch
值没有改变。如果这不是你想要的,其他答案可能更容易。查询#1
View on DB Fiddle
编辑:
更新答案以从最终选择中删除不需要的行:
jchrr9hc2#
我不知道这是不是你想要的,但试试这个:
ogsagwnx3#
原来的表设计有一些问题,最麻烦的是 families 和 products 是相互引用的,从 families 到 products 的外键关联没有在DDL中声明这种设计所导致的问题之一是无法使用约束来确保 families.main_product_id 和 products. families_id 相互一致。我通过从 families 中删除 main_product_id 并向 products 添加布尔标志 is_main_product 来重构表。部分唯一索引强制约束每个家族只能有一个主产品。
我还做了以下与原始问题无关的更改,但改进了模型:
1.为 name 列添加了唯一约束。
1.将布尔列
NOT NULL
设置为默认值。对布尔列的更改有助于避免在计算逻辑表达式时与处理
NULL
相关的额外复杂性。以下是修改后的表创建语句:
请注意,使用索引强制执行一个系列只能有一个主要产品的规则会导致一个问题:更改主产品需要两次更新,一次是将当前主产品的 is_main_product 设置为false,另一次是将新主产品的 is_main_product 设置为true。由于两次更新都可以在同一事务中发生,因此这应该是一个小小的不便。
我修改了insert,以消除对生成的 id 值的显式依赖。这有助于确保 id 值和相关序列同步。
以下查询返回的输出与原始问题中发布的示例一致: