我有以下的MS Access數據庫架構:爲每個組選擇前N行
我想選擇由Items.score訂購的商品表中的行,這樣最多有Group.top_count每組的行數。
例如,我有表中的以下數據:
組表:
項目表:
我要選擇頂部2項對於組#1和組#1的前1個項目。所以結果必須包含行1,2和5.
有一個similar question at DBA stackexchange,但關於SQL Server。所以所有的答案都使用了SQL Server語法,我無法使它適應MS Access。
我有以下的MS Access數據庫架構:爲每個組選擇前N行
我想選擇由Items.score訂購的商品表中的行,這樣最多有Group.top_count每組的行數。
例如,我有表中的以下數據:
組表:
項目表:
我要選擇頂部2項對於組#1和組#1的前1個項目。所以結果必須包含行1,2和5.
有一個similar question at DBA stackexchange,但關於SQL Server。所以所有的答案都使用了SQL Server語法,我無法使它適應MS Access。
如果每組有一個常數,你可以這樣做:
select i.*
from items as i inner join
groups as g
on i.group_id = g.id
where i.id in (select top 2 i2.id
from items i2
where i2.group_id = i.group_id
order by i2.score desc
);
相反,你將需要枚舉值,這是昂貴的MS Access:
select i.*
from (select i.*,
(select count(*)
from items i2
where i2.group_id = i.group_id and
(i2.score < i.score or
i2.score = i.score and i2.id <= i2.id
)
) as seqnum
from items as i
) as i inner join
groups as g
on i.group_id = g.id
where i.seqnum <= g.top_count;
這個邏輯實現相當於row_number()
,這是解決此問題的正確方法(如果數據庫支持它)。
使用VBA創建SQL命令,可能試試這個(未經測試)。它基本上創建了一個連接每個分組的UNION,並允許您在任意大小的表上運行它(不確定UNION是否有限制,並且在多次之後它開始陷入困境,或者有更好的方法可以打開一個記錄集/表,並且只是將結果寫入該記錄集/表而不是執行UNION的事情。
SET DBS = CURRENTDB
strSQL = ""
intMax = dmax("ID", "group")
FOR i = 1 TO intMax
strSQL = strSQL & "SELECT TOP " & DLOOKUP("top_count","group","ID = " & I) & " ID " & _
"FROM items WHERE group_id = " & i & " ORDER BY score "
if i < intMax
strSQL = strSQL & " UNION "
endif
next i
dbs.execute strSQL