在Django-ORM语法中在同一层次结构中的不同类之间使用UNION

2024-04-29 01:05:52 发布

您现在位置:Python中文网/ 问答频道 /正文

我需要实施类似

 (SELECT table1.*, val=2 FROM table1 INNER JOIN table2 ON table1.id = table2.id WHERE some_condition)
 UNION
 (SELECT table1.*, val=3 FROM table1 INNER JOIN table3 ON table1.id = table3.id WHERE some_condition)

或者

^{pr2}$

也就是说,拥有“table1”、“table2”和“table3”类,其中table2和table3是从table1派生的,我需要用附加字段选择所有这些类。问题是,我宁愿避免使用原始sql查询,因为有些条件应该是可重用的。如果我尝试使用extra,它会抱怨我使用.extra。在


Tags: fromidonvalsomewhereconditionselect
3条回答

如果您试图在.execute调用之外编写这个JOIN/UNION,那么您将花费大量时间与djangoormapi进行斗争。如果这将是非常常见的,考虑使用^{},然后从新创建的VIEW中执行一个简单的SELECT。在

您可以将其重写为子查询:

select val1, val2, val3, val4
from (
     SELECT val1, val2, val3, val=2 as val4 FROM table2
     UNION
     SELECT val1, val2, val3, val=3 as val4 FROM table3
     ) t
where some_condition

但是要小心,因为这不一定是最好的选择。在

这可能是令人满意的,因为您避免重写条件,但是对于查询规划器来说,这两个查询可能是非常不同的动物。Postgres偶尔会聪明到可以将where条件注入到子语句中,但我从未见过这样做的一个例子是当子语句具有任何类型的聚合时。在

具体地说,如果条件放在外部(如上所述),您将首先附加两个完整的表。然后聚合它们以消除重复项(这是一个避免使用union all而不是union,顺便说一句)的步骤,最后过滤结果集中与您的条件匹配的行。在

相比之下,当放在单个位中时,您将追加并排序两个较小的行集。它会更快,消耗更少的内存。在

简而言之,在查询中尽可能早地过滤行。在

我决定移植到sqlalchemy——我的问题很适合django,我更喜欢使用tg2(也就是说,这并不意味着django不好——它只是不适合我的任务)。在

相关问题 更多 >