使用外部联接并限制每个父级的子记录的SQL查询 [英] SQL query using outer join and limiting child records for each parent

查看:53
本文介绍了使用外部联接并限制每个父级的子记录的SQL查询的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在弄清楚如何构造SQL查询时遇到了麻烦.假设我们有一个User表和一个Pet表.每个用户可以养很多只宠物,并且Pet有一个繁殖"列.

I'm having trouble figuring out how to structure a SQL query. Let's say we have a User table and a Pet table. Each user can have many pets and Pet has a breed column.

User:

id    |    name
______|________________
1     |    Foo
2     |    Bar

Pet:

id    |    owner_id    |    name    |    breed    |
______|________________|____________|_____________|
1     |        1       |  Fido      |  poodle     |   
2     |        2       |  Fluffy    |  siamese    |

最终目标是提供一个查询,该查询将为我提供与给定where子句匹配的每个用户的所有宠物,同时允许使用sortlimit参数.因此,可以将每个用户的宠物限制为5个并按名称排序.

The end goal is to provide a query that will give me all the pets for each user that match the given where clause while allowing sort and limit parameters to be used. So the ability to limit each user's pets to say 5 and sorted by name.

我正在为ORM动态构建这些查询,因此我需要一个可以在MySQL和Postgresql中运行的解决方案(尽管它可以是两个不同的查询).

I'm working on building these queries dynamically for an ORM so I need a solution that works in MySQL and Postgresql (though it can be two different queries).

我已经尝试过类似的方法,但这种方法不起作用:

I've tried something like this which doesn't work:

SELECT "user"."id", "user"."name", "pet"."id", "pet"."owner_id", "pet"."name",
  "pet"."breed"
FROM "user"
LEFT JOIN "pet" ON "user"."id" = "pet"."owner_id"
WHERE "pet"."id" IN
  (SELECT "pet"."id" FROM "pet" WHERE "pet"."breed" = 'poodle' LIMIT 5)

推荐答案

Postgres (8.4或更高版本)中,使用

In Postgres (8.4 or later), use the window function row_number() in a subquery:

SELECT user_id, user_name, pet_id, owner_id, pet_name, breed
FROM  (
   SELECT u.id AS user_id, u.name AS user_name
        , p.id AS pet_id, owner_id, p.name AS pet_name, breed
        , row_number() OVER (PARTITION BY u.id ORDER BY p.name, pet_id) AS rn
   FROM  "user"    u
   LEFT   JOIN pet p ON p.owner_id = u.id
                    AND p.breed = 'poodle'
   ) sub
WHERE  rn <= 5
ORDER  BY user_name, user_id, pet_name, pet_id;

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆