Mysql

具有相關數據(帶連接)的行的限制和偏移(分頁)

  • September 4, 2021

我有桌子AlphaBeta. Beta屬於Alpha.

create table Alpha
(
   id int auto_increment primary key
);

create table Beta
(
   id         int auto_increment primary key,
   alphaId    int null,
   orderValue int,
   constraint Alpha_ibfk_1 foreign key (alphaId) references Alpha (id)
);

以下是一些測試記錄:

insert into Alpha (id) values (1);
insert into Alpha (id) values (2);
insert into Beta (id, alphaId, orderValue) values (1, 1, 23);
insert into Beta (id, alphaId, orderValue) values (2, 1, 43);
insert into Beta (id, alphaId, orderValue) values (3, 2, 73);

我想為他們創建一個分頁,這在我的應用程序邏輯方面是有意義的。因此limit 2,例如,當我設置時,我希望獲得兩條Alpha記錄及其相關記錄的列表,但實際上當我設置時limit 2

   select *
from Alpha
     inner join Beta on Alpha.id = Beta.alphaId
order by Beta.orderValue
limit 2;

結果我只有一個 Alpha 記錄及其相關數據:

[

雖然我想找出一種方法讓我的LIMIT構造只計算唯一出現的Alpha記錄並返回如下內容:

在此處輸入圖像描述

是否可以在一次查詢中在 MySQL 中完成?也許不同的RDBMS?還是進行多個查詢是唯一的選擇?

=== 編輯

這種要求的原因是我想創建一個帶有分頁的 API,它返回 Alpha 的記錄及其相關的 Beta 記錄。問題是從使用者的角度來看,限制的工作方式沒有意義:"Hey, I said I want 2 records of Alpha with its related data, not 1. What is that?"

如果您使用的是支持標準視窗函式的數據庫,則可以使用dense_rank()對 distinct Alpha.ids 進行編號:

select * from (
 select 
   a.id as a_id, b.id as b_id, b.alphaid,  
   dense_rank() over (order by a.id) as alpha_rank
 from Alpha a inner join Beta b on a.id=b.alphaid
) as t
where alpha_rank <= 2

小提琴

使用不支持視窗函式的早期 MySQL 版本,您可以使用變數笨拙地模擬:

select * from (
 select x.*
   ,@rank := case when a_id = @remember_a_id then @rank else @rank+1 end as alpha_rank
   ,@remember_a_id := a_id
 from
   (select a.id as a_id, b.id as b_id, b.alphaid
    from Alpha a 
    inner join Beta b on a.id=b.alphaid 
    order by a.id, b.id) as x
 cross join (select @rank:=0) as y
 cross join (select @remember_a_id:=null) as z
) as t
where alpha_rank <=2

儘管我懷疑有時訂單可能不正確;你需要在你的真實數據上進行測試。

小提琴

引用自:https://dba.stackexchange.com/questions/299008