django orm中的INNER JOIN

Posted

技术标签:

【中文标题】django orm中的INNER JOIN【英文标题】:INNER JOIN in django orm 【发布时间】:2021-11-25 11:08:50 【问题描述】:

我有两个表,它们只包含相同的产品 ID,并且它们没有外键。所以问题是关于我如何在查询中通过 id 过滤它们。 在 SQL 中,我想做这样的事情

SELECT Url FROM pricehistory p INNER JOIN product d ON p.ProductID = d.ProductID 

模型如下所示:

class Product(models.Model):
   ProductID = models.CharField(..)
   Price = models.FloatField(..)
   Url = models.CharField(..)
   ....

class PriceHistory(models.Model):
  ProductID = models.CharField(..)
  Price = models.FloatField(..)
  Retailer = models.CharField(..)
  Timestamp = models.DateTimeField(..)

【问题讨论】:

请分享您的模型。 这里是..... Product模型上的ProductID是主键吗?为什么 PriceHistory 上的 ProductID 列未定义为 Product 模型的 ForeignKey? 【参考方案1】:

您可以使用Exists(…) subquery [Django-doc] 进行过滤:

from django.db.models import Exists, OuterRef

Product.objects.filter(
    Exists(PriceHistory.objects.filter(ProductID=OuterRef('ProductID')))
).values('Url')

这不会执行INNER JOIN,但会生成一个WHERE EXISTS (…) 子查询,该子查询将只保留Products 中的Urls,这些@s 具有PriceHistory

我建议将ProductID 转换为引用ProductProductIDForeignKey,所以:

class Product(models.Model):
    ProductID = models.CharField(unique=True)
    # …

class PriceHistory(models.Model):
    ProductID = models.ForeignKey(
        Product,
        to_field='ProductID',
        on_delete=models.CASCADE,
        db_column='ProductID'
    )
  # …

这会将ProductProductID 存储在数据库中,同时保证引用完整性,并使得使用Django ORM 进行查询更加方便。

【讨论】:

以上是关于django orm中的INNER JOIN的主要内容,如果未能解决你的问题,请参考以下文章

轻量级ORM框架——第二篇:Dapper中的一些复杂操作和inner join应该注意的坑

轻量级ORM框架——第二篇:Dapper中的一些复杂操作和inner join应该注意的坑

将非 FK 条件添加到 Django ORM 中的 LEFT OUTER JOIN 以返回不连接的行

Django - 遵循外键关系(即 SQL 中的 JOIN)

来自INNER JOIN的Django SUM

SQL中的CROSS JOIN与INNER JOIN