2013-08-14 33 views
6

tôi cần một chút trợ giúp. Tôi có truy vấn sau đây và tôi tò mò về cách đại diện cho nó về sqlalchemy.orm. Hiện tại tôi đang thực hiện nó bằng session.execute. Nó không quan trọng đối với tôi, nhưng tôi chỉ tò mò thôi. Điều mà tôi thực sự không biết là làm thế nào để đặt truy vấn phụ trong mệnh đề FROM (xem lồng nhau) mà không thực hiện bất kỳ phép nối nào.Truy vấn con của SQLAlchemy trong mệnh đề từ mà không cần tham gia

select g_o.group_ from (
    select distinct regexp_split_to_table(g.group_name, E',') group_ 
     from (
      select array_to_string(groups, ',') group_name 
      from company 
      where status='active' 
      and array_to_string(groups, ',') like :term 
      limit :limit 
     ) g 
    ) g_o 
where g_o.group_ like :term 
order by 1 
limit :limit 

tôi cần điều subquery này vì vấn đề tốc độ - không có giới hạn trong hàm truy vấn bên trong hầu hết regexp_split_to_table bắt đầu để phân tích tất cả các dữ liệu và không giới hạn chỉ sau đó. Nhưng bảng của tôi là rất lớn và tôi không thể đủ khả năng đó.

Nếu có điều gì đó không rõ ràng, hãy hỏi, tôi sẽ làm hết sức mình)

Trả lời

8

Tôi cho rằng đây là PostgreSQL.

Để tạo truy vấn phụ, hãy sử dụng phương thức subquery(). Đối tượng kết quả có thể được sử dụng như thể nó là đối tượng Table. Sau đây là cách truy vấn của bạn sẽ trông như thế nào trong SQLAlchemy:

subq1 = session.query(
    func.array_to_string(Company.groups, ',').label('group_name') 
).filter(
    (Company.status == 'active') & 
    (func.array_to_string(Company.groups, ',').like(term)) 
).limit(limit).subquery() 

subq2 = session.query(
    func.regexp_split_to_table(subq1.c.group_name, ',') 
     .distinct() 
     .label('group') 
).subquery() 

q = session.query(subq2.c.group).\ 
    filter(subq2.c.group.like(term)).\ 
    order_by(subq2.c.group).\ 
    limit(limit) 

Tuy nhiên, bạn có thể tránh được một subquery bằng cách sử dụng chức năng unnest thay vì chuyển đổi mảng chuỗi với arrayt_to_string và sau đó tách nó với regexp_split_to_table:

subq = session.query(
    func.unnest(Company.groups).label('group') 
).filter(
    (Company.status == 'active') & 
    (func.array_to_string(Company.groups, ',').like(term)) 
).limit(limit).subquery() 

q = session.query(subq.c.group.distinct()).\ 
    filter(subq.c.group.like(term)).\ 
    order_by(subq.c.group).\ 
    limit(limit) 
Các vấn đề liên quan