代码之家  ›  专栏  ›  技术社区  ›  Murat Ayfer

如何使用django orm执行这个复杂的SQL查询?(带联接的子查询)

  •  3
  • Murat Ayfer  · 技术社区  · 15 年前

    我习惯于编写我自己的SQL查询,并且我正在尝试适应现在看来非常流行的整个ORM。

    以下是问题:

    SELECT * FROM routes WHERE route_id IN (
        SELECT DISTINCT t.route_id FROM stop_times AS st 
        LEFT JOIN trips AS t ON st.trip_id=t.trip_id
        WHERE stop_id = %s
    )
    

    其中%s是整数。

    我使用的是Django的默认ORM。做这件事最要紧的方法是什么?

    一些背景信息:我使用的数据库来自一个gtfs(google transit feed规范)。此查询应获取 route 经历了一个特殊的 stop 但是,链接这些内容的信息位于 trips 表。

    这个问题对我来说很好,所以我问的唯一原因就是学习。

    谢谢!

    2 回复  |  直到 14 年前
        1
  •  1
  •   desfido    15 年前

    如果您有相关的使用方法,那么找到合适的方法可能会容易一些。 Models

    根据您提到的工作规范,我假设如下:

    class Route(models.Model):
        #bunch of stuff
        pass
    class Stop(models.Model):
        #bunch of stuff
        stop_times = models.ManyToManyField(through=StopTime)
    class StopTime(models.Model):
        trip = models.ForeignKey(Trip)
        stop = models.ForeignKey(Stop)
        # bunch of additional meta about this M2M table
        pass
    class Trip(models.Model):
        route = models.ForeignKey(Route)
        # bunch of stuff
    

    如果是这样的话…你应该能做些像

    Route.objects.filter(trip__stop__id=my_stop_id)
    

    得到全部 Route 通过给定对象 Stop 使用主键 id 等于 my_stop_id ,我假设这是一个整数。

    如果语法有点不正确,我很抱歉,因为我不需要使用显式的额外表来处理多对多关系。如果必须(或选择)使用 related_name 任何外键或多对多字段的参数。

        2
  •  1
  •   Wolph    15 年前

    如果我错了,请纠正我,但我认为你不能以正常的方式使用django orm。

    没有子查询支持,如果distinct可以帮助您,使用普通联接,它将依赖于您的数据库。如果您使用的是Postgres,那么您可以使用这个补丁: http://code.djangoproject.com/ticket/6422

    查询如下所示:

    Route.objects.filter(stop_time__trips__stop_id=...).distinct('stop_time__route_id')