簡體   English   中英

SQLAlchemy | 將連接結果限制為一對多關系的一行

[英]SQLAlchemy | Limit join result to one row for one-to-many relationship

我有兩個實體:項目和學生列表。 一個項目可以有多個學生列表。

我正在嘗試加入項目的學生列表,並且僅根據學生列表的自定義排序返回每個項目的第一行。

嘗試的子查詢:

_whens = {ProjectStatus.APPROVED: 1, ProjectStatus.REJECTED: 2, 
          ProjectStatus.SUBMITTED: 3, None: 4}
sort_order = case(value=StudentList.student_list_status_id, whens=_whens)

return self._session.query(StudentList).
        filter(StudentList.student_list_id==Project.project_id)
       .order_by(sort_order).limit(1).subquery()

上面我定義了基於學生列表狀態 ID 的自定義排序。 該函數返回子查詢,然后我嘗試將其加入下面的項目外查詢(student_list_subquery 指的是上面返回的內容):

projects = self._session.query(models.Project)
            .filter(models.Project.project_year == year)
            .join(student_list_subquery,
            student_list_subquery.c.project_id==Project.project_id)
            .all()

下面是相關的 SQL 輸出

FROM project 
LEFT OUTER JOIN (SELECT student_list.project_id AS project_id, 
 student_list.student_list_id AS student_list_id
 FROM student_list, project
 WHERE project.project_id = student_list.project_id 
 ORDER BY CASE student_list.student_list_status_id WHEN 102 THEN 1 
 WHEN 105 THEN 2 WHEN 101 THEN 3 WHEN NULL THEN 4 END
 LIMIT 1) AS anon_1 ON anon_1.project_id = project.project_id

我正在使用 mySQL,所以 (Distinct On) 解決方案將不起作用,row_number/partition 解決方案也不會......

我似乎在這里提出了同樣的問題SQLAlchemy: FROM entry still present in related subquery

終於解決了問題。 希望這有助於其他人在需要使用 SQLAlchemy 和 mySQL 對組進行自定義排序時嘗試解決每個組中的 first-n-per-group 問題。

首先,我有這個函數返回一個具有最高優先級的 student_list_status_id 項目(因此是過濾器)。

@staticmethod
def create_student_list_subquery(session):
    '''create a correlated subquery that will limit result to one student
    list per project with custom sorting to retrieve highest priority list
    per project based on status'''

    sl2=aliased(StudentList)
    list_id = sl2.student_list_status_id.label("list_id")
    _whens = {ProjectStatus.APPROVED: 1, ProjectStatus.REJECTED: 2, 
             ProjectStatus.SUBMITTED: 3, None: 4}
    sort_order = case(value=list_id, whens=_whens)

    return session.query(list_id).filter(sl2.project_id==Project.project_id)
                  .order_by(sort_order)
                  .limit(1)

I join 項目狀態與上面查詢中的 student_list_status_id 相關(別名為 ps)到項目中。 然后,我可以對項目狀態名稱進行排序,這是我的目標。

self._session.query(models.Project)
        .filter(models.Project.project_year == year)
        .join(ps, ps.project_status_id==student_list_subq)
        .all()

注意 student_list_subq 指的是上面 create_student_list_subquery 函數的結果。

我有類似的問題。 解決方案是使用 LATERAL sqlalchemy 方法:

subquery = select([student_list.c.project_id, student_list.c.student_list_id])\
               .where(student_list.c.project_id == project.project_id)\
               .limit(1)\
               .lateral('students')
query = select([project.c.project_name, subquery.c.project_id, subquery.c.student_list_id])\
               .select_from(project.join(subquery))

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM