Sql 如何从一组有序的行中选择下一行和上一行?

Sql 如何从一组有序的行中选择下一行和上一行?,sql,database,laravel,eloquent,Sql,Database,Laravel,Eloquent,我将根据如下金额对前3个订单进行切片: Order::orderByDesc('amount')->take(3)->get(); 但现在,我必须再进一步。订单表有一个由创建的列,该列与创建者(belongsTo)关系相关联。首先,我必须根据数量对订单进行排序,然后我必须取5个订单的一个订单,其中给定的 CREATEDY按值位于中间(5个记录中的第三个)。要将其转换为业务逻辑,请执行以下操作: 显示特定用户在排行榜上的位置,以及领先和落后的其他两名成员 考虑到我们要获取其数据的Ca

我将根据如下金额对前3个订单进行切片:

Order::orderByDesc('amount')->take(3)->get();
但现在,我必须再进一步。
订单
表有一个由创建的
列,该列与
创建者
(belongsTo)关系相关联。首先,我必须根据数量对订单进行排序,然后我必须取5个订单的一个订单,其中给定的<代码> CREATEDY按值位于中间(5个记录中的第三个)。要将其转换为业务逻辑,请执行以下操作:

显示特定用户在排行榜上的位置,以及领先和落后的其他两名成员

考虑到我们要获取其数据的Carol,可视表示可能如下所示:

Order::orderByDesc('amount')->take(3)->get();
  • 1 |名称:Alice |订单金额:500美元
  • 2 |名称:Bob |订单金额:400美元
  • 3 | Name:Carol |订单金额:$300//登录用户
  • 4 |姓名:戴安娜|订单金额:200美元
  • 5 |姓名:Emma |订单金额:$100

我能想到的一种实现方法是将所有排序的顺序提取到一个集合中,然后查找下一行和前两行,但对于大型数据集,这将消耗大量内存。如何以雄辩的/以数据库为中心的方式实现这一点,而不是获取所有数据,然后应用收集操作?

我了解SQL,使用窗口函数很容易做到这一点。 如果您知道记录在“领导委员会”中的位置,例如3

SELECT
    o.name,
    o.amount
FROM (
    SELECT
        o.created_by,
        o.amount,
        ROW_NUMBER() OVER (ORDER BY o.amount DESC) AS rn
    FROM Order o
) s
JOIN Creator c on c.id = s.created_by
WHERE
    s.rn BETWEEN 3 - 2 AND 3 + 2
如果您只知道创建者的姓名:

WITH Ranked (name, amount, rn)
AS (
    SELECT
        o.name,
        o.amount,
        ROW_NUMBER() OVER (ORDER BY o.amount DESC) AS rn
    FROM Order o   
    JOIN Creator c on c.id = o.created_by
)
SELECT 
    o.name,
    o.amount
FROM Ranked r
JOIN Ranked o ON o.rn BETWEEN r.rn - 2 AND r.rn + 2
WHERE r.name = `Carol`

它不是laravel查询,但您应该知道如何执行原始SQL,它可以为您提供正确的方向,如何编写有效的查询。

您可以进行3次查询。。一个用于获取登录的用户数据,一个用于上一个用户,另一个用于下一个用户。基于登录用户数量的第二次和第三次查询高级用户:Order::orderByAsc('amount')->其中('amount','>','$user->amount')->take(2)->get()。。。。。。。在这两个查询中,您都获取了所有订单。这不是一个性能问题吗?