Mysql
具有相關數據(帶連接)的行的限制和偏移(分頁)
我有桌子
Alpha
和Beta
.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()
對 distinctAlpha.id
s 進行編號: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
儘管我懷疑有時訂單可能不正確;你需要在你的真實數據上進行測試。