Фильтрация результатов базы данных по верхним n записям для каждого значения в столбце поиска - PullRequest
1 голос
/ 14 февраля 2011

Допустим, у меня есть две таблицы в моей базе данных.

TABLE:Categories
ID|CategoryName
01|CategoryA
02|CategoryB
03|CategoryC

и таблица, которая ссылается на категории, а также содержит столбец, в котором хранится случайное число.

TABLE:CategoriesAndNumbers
CategoryType|Number
   CategoryA|24
   CategoryA|22
   CategoryC|105
   .....(20,000 records)
   CategoryB|3

Теперь, как мне отфильтровать эти данные? Итак, я хочу знать, какие 3 самых маленьких числа находятся в каждой категории, и удалить остальные. Конечный результат будет таким:

TABLE:CategoriesAndNumbers
CategoryType|Number
   CategoryA|2
   CategoryA|5
   CategoryA|18
   CategoryB|3
   CategoryB|500
   CategoryB|1601
   CategoryC|1
   CategoryC|4
   CategoryC|62

Сейчас я могу получить наименьшее число между всеми категориями, но я бы хотел, чтобы каждая категория сравнивалась по отдельности.

РЕДАКТИРОВАТЬ: я использую Access и вот мой код пока

SELECT TOP 10 cdt1.sourceCounty, cdt1.destCounty, cdt1.distMiles
FROM countyDistanceTable as cdt1, countyTable
WHERE cdt1.sourceCounty = countyTable.countyID
ORDER BY cdt1.sourceCounty, cdt1.distMiles, cdt1.destCounty

РЕДАКТИРОВАТЬ2: Благодаря Remou, здесь будет рабочий запрос, который решил мою проблему. Спасибо!

DELETE
FROM CategoriesAndNumbers a
WHERE a.Number NOT IN (
    SELECT Top 3 [Number] 
    FROM CategoriesAndNumbers b 
    WHERE b.CategoryType=a.CategoryType 
    ORDER BY [Number])

Ответы [ 2 ]

1 голос
/ 14 февраля 2011

Вы можете использовать что-то вроде:

SELECT a.CategoryType, a.Number
FROM CategoriesAndNumbers a
WHERE a.Number IN (
    SELECT Top 3 [Number] 
    FROM CategoriesAndNumbers b 
    WHERE b.CategoryType=a.CategoryType 
    ORDER BY [Number])
ORDER BY a.CategoryType

Сложность в том, что Jet / ACE Top выбирает дубликаты значений там, где они существуют, поэтому вы не обязательно получите три значения, но больше, если есть связи. Часто проблему можно решить с помощью ключевого поля, если оно существует:

WHERE a.Number IN (
    SELECT Top 3 [Number] 
    FROM CategoriesAndNumbers b 
    WHERE b.CategoryType=a.CategoryType 
    ORDER BY [Number], [KeyField])

Однако я не думаю, что это поможет в этом случае, потому что внешняя таблица будет включать связи.

0 голосов
/ 14 февраля 2011

Упорядочите его по номеру и возьмите 3, выясните, какое наибольшее число, а затем удалите строки, где Number больше, чем Number.

Я предполагаю, что потребуется два отдельных запроса.поскольку ваш бизнес-уровень будет содержать значение для наибольшего числа из 3-х результатов и динамически создавать запрос для удаления остальных.

...