2016-09-26 4 views
0

У меня есть следующий MS Access DB схема:Выбрать верхние N строк для каждой группы

DB schema

Я хочу, чтобы выбрать строки из таблицы Items заказанного Items.score так, что есть в большинстве Group.top_count строк для каждой группы.

Например, у меня есть следующие данные в таблицах:

Группа таблицы:

Group table

Элементы таблицы:

Items table

Я хочу, чтобы выбрать верхние 2 пунктов для группы №1 и первой позиции для группы №2. Таким образом, результат должен содержать строки 1, 2 и 5.

Был similar question at DBA stackexchange, но о SQL Server. Таким образом, все ответы использовали синтаксис SQL Server, и я не мог его адаптировать для работы с MS Access.

ответ

2

Если бы было постоянное число в группе, вы можете сделать:

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(), что является правильным способом решения этой проблемы (если ваша база данных поддерживает ее).

0

Использование VBA для создания команды SQL, возможно, попробуйте это (непроверено). Он в основном создает 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 
Смежные вопросы