2012-04-11 2 views
1

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

Примерный набор данных ниже показывает двух клиентов; у каждого из клиентов есть другой продукт. С NumRowsToShow «1» Я хочу показать только одну строку (верхнюю строку на основе порядкового номера) для КАЖДОГО клиента.

| CustomerID | ProductID | Ordinal | NumRowsToShow | 
+------------+-----------+---------+---------------+ 
| 1   |A   |1  |1    | 
| 1   |B   |2  |1    | 
| 1   |C   |3  |1    | 
| 5   |D   |1  |1    | 
| 5   |E   |2  |1    | 
| 5   |F   |3  |1    | 

Результат устанавливается после запроса запуска должен быть

| CustomerID | ProductID | 
+------------+-----------+ 
| 1   |A   | 
| 5   |D   | 

В том же случае, если NumRowsToShow были 1 для CUSTOMERID 1 и 2 для CustomerID 5 я хотел бы видеть что-то подобное.

| CustomerID | ProductID | Ordinal | NumRowsToShow | 
+------------+-----------+---------+---------------+ 
| 1   |A   |1  |1    | 
| 1   |B   |2  |1    | 
| 1   |C   |3  |1    | 
| 5   |D   |1  |2    | 
| 5   |E   |2  |2    | 
| 5   |F   |3  |2    | 

Результат устанавливается после запроса запуска должен быть

| CustomerID | ProductID | 
+------------+-----------+ 
| 1   |A   | 
| 5   |D   | 
| 5   |E   | 

Как это можно сделать?

Включая экранный экран фактического набора результатов с основными моментами того, что я пытаюсь отфильтровать, к чему может быть полезно.

Screencap http://www.harpernet.net/se/cap01.jpg

+1

А что, если строки клиента было три различных 'NumRowsToShow' (скажем 1,2,3)? –

+0

Этого не произойдет; NumRowsToShow поставляется с настройкой на CustomerID. Это то же самое. Это результат нескольких запросов. Клиент/ProductID не являются фактическими наборами результатов, я просто пытаюсь предоставить простой пример того, что я пытаюсь отфильтровать. – sugarcrum

ответ

6

Он чувствует, как «обман на экзаменах»:

SELECT CustomerID, ProductID 
FROM tableX 
WHERE Ordinal <= NumRowsToShow 

Если, как комментарии предполагают, то Ordinal может иметь 10, 20, 30 значения, а не только 1, ..., n значения, то это будет работы:

SELECT t.CustomerID, t.ProductID 
FROM tableX AS t 
    JOIN tableX AS tt 
    ON tt.CustomerID = t.CustomerID 
    AND tt.Ordinal <= t.Ordinal 
GROUP BY t.CustomerID 
     , t.ProductID 
     , t.NumRowsToShow 
HAVING COUNT(*) <= t.NumRowsToShow 

или даже лучше,:

SELECT CustomerID, ProductID 
FROM 
    (SELECT CustomerID, ProductID, NumRowsToShow 
     , ROW_NUMBER() OVER(PARTITION BY CustomerID 
           ORDER BY Ordinal 
          ) AS Rn 
    FROM tableX 
) AS tmp 
WHERE Rn <= NumRowsToShow ; 

испытания в: SQL-Fiddle


Ваш стол выглядит не нормируется. Столбцы NumRowsToShow имеют повторяющуюся информацию, что может привести к обновлению аномалий. Это:

| CustomerID | ProductID | Ordinal | NumRowsToShow | 
+------------+-----------+---------+---------------+ 
| 1   |A   |1  |1    | 
| 1   |B   |2  |1    | 
| 1   |C   |3  |1    | 
| 5   |D   |1  |2    | 
| 5   |E   |2  |2    | 
| 5   |F   |3  |2    | 

может быть нормирована на 2 таблицы:

| CustomerID | ProductID | Ordinal | 
+------------+-----------+---------+ 
| 1   |A   |1  | 
| 1   |B   |2  | 
| 1   |C   |3  | 
| 5   |D   |1  | 
| 5   |E   |2  | 
| 5   |F   |3  | 

и:

| CustomerID | NumRowsToShow | 
+------------+---------------+ 
| 1   |1    | 
| 5   |2    | 
+0

Таблица является результатом другого запроса; это просто используется в качестве простого примера результирующего набора данных, который я пытаюсь отфильтровать. Мне нравится простой подход Ordinal <= NumRowsToShow. Он почти работает, за исключением того, что «Ординал» может быть 10, 20, 30 .. не должен быть 1, 2,3. – sugarcrum

+0

Большое спасибо за то, что нашли время для ответа. Утверждение раздела - именно то, что я искал. Я шел по этой дороге, но не мог найти правильный способ ее структурирования. Очень, очень ценю за помощь. – sugarcrum

Смежные вопросы