2009-05-05 1 views
0

Мы хотим иметь возможность выбирать верхние N строк с помощью SQL Query. Целевой базой данных может быть Oracle или MySQL. Есть ли элегантный подход к этому? (Разумеется, мы имеем дело с отсортированными данными здесь.)Может ли быть SQL-агностический SQL-запрос для извлечения верхних N строк?

ответ

2

Чтобы получить 5 лучших бомбардиров из этой таблицы:

CREATE TABLE people 
      (id  int, 
       name string, 
       score int) 

попробовать этот SQL:

SELECT id, 
     name, 
     score 
FROM people p 
WHERE (SELECT COUNT(*) 
     FROM people p2 
     WHERE p2.score > p.score 
     ) <=4 

Я считаю, что это должно работать в большинстве мест.

2

№. Синтаксис отличается.

Вы можете, однако, создавать представления:

/* Oracle */ 

CREATE VIEW v_table 
AS 
SELECT * 
FROM (
     SELECT * 
     FROM table 
     ORDER BY 
       column 
     ) 
WHERE rownum <= n 

/* MySQL */ 

CREATE VIEW v_table 
AS 
SELECT * 
FROM table 
ORDER BY 
     column 
LIMIT n 
+1

Ограничение принуждения к заказу вашего вида (по крайней мере, на SQL-сервере при использовании предложения TOP n). – Tomalak

+1

И другие СУБД поддерживают концепцию, но используют другие обозначения. –

+0

Кроме того, некоторые СУБД не допускают предложение ORDER BY в представлении. –

1

Я не думаю, что это возможно, даже просто между MySQL и MSSQL. Я делаю выбор для моделирования такого поведения:

  1. создавать представления с автоматической инкрементной колонкой int; сказать «PagingHelperID»
  2. запросов записи, как: SELECT columns FROM viewname WHERE PagingHelperID BETWEEN startindex AND stopindex

Это сделает заказ сложно, вам понадобятся различные представления для каждого заказа, в котором вы собираетесь извлечь данные.

Вы также можете «переписать» свой sql на лету при запросе в зависимости от базы данных и определить свой собственный метод для перезаписывающего устройства, но я не думаю, что есть «хороший» способ сделать это.

+0

Справа. Я хочу избежать любого обнаружения базы данных. – pugmarx

1

Если есть уникальный ключ на столе да ...

Select * From Table O 
Where (Select Count(*) From Table I 
     Where [UniqueKeyValue] < O.UniqueKeyValue) < N 

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

EDIT: Если «сортировка», определяющая значение «Верх», основана на уникальном столбце или наборе столбцов, то вы все равно можете использовать это, но вы не можете гарантировать вам смогут получить ровно N записей ...

Select * From Table O 
    Where (Select Count(*) From Table I 
     Where nonUniqueCol < O.nonUniqueCol) < 10 

Если записи 8, 9, 10, 11 и 12 имеют одинаковое значение в [nonUniqueCol], тогда запрос будет генерировать только 7 записей (с «<») ... или 12 (если вы используете «< =»)

ПРИМЕЧАНИЕ: Поскольку это предполагает коррелированный подзапрос, производительность может быть проблемой для очень больших таблиц ...

+0

Что делать, если ваши уникальные ключи являются GUID или некоторыми другими несекретными данными? –

+0

Уникальный ключ позволяет вам идентифицировать записи ... если «сортировка», которая определяет значение «Верх», основана на какой-либо другой другой логике, тогда подзапрос будет записан для «подсчета» записей на основе этого логика ... Единственная проблема тогда в том, что если значение N происходит по определенному значению, где есть несколько экземпляров .... (если записи 8, 9, 10 и 11 имеют одинаковое значение, вы можете получить t Топ 10) –

0

Большая проблема, рассмотрев это, заключается в том, что MySQL не соответствует требованиям ISO SQL: 2003. Если бы это было, вы бы эти удобные функции управления окнами:

SELECT * from 
( SELECT 
    RANK() OVER (ORDER BY <blah>) AS ranking, 
    <rest of columns here>, 
    FROM <table> 
) 
WHERE ranking <= <N> 

Увы, MySQL (и другие, которые имитируют его поведение, например, SQLite), не, следовательно, весь предельный вопрос.

Проверьте этот фрагмент из Википедии (http://en.wikipedia.org/wiki/Window_function_(SQL)#Limiting_result_rows)

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