Может ли быть независимый от базы данных SQL-запрос для выборки первых N строк?

0

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

Теги:
database
database-agnostic

6 ответов

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).
  • 1
    И другие СУБД поддерживают эту концепцию, но используют другие обозначения.
Показать ещё 3 комментария
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
    Уникальный ключ позволяет идентифицировать записи ... если «сортировка», определяющая значение «Top», основана на какой-то другой логике, то подзапрос будет записан для «подсчета» записей на основе этой логики. ... Единственная проблема заключается в том, что если значение N встречается с конкретным значением, в котором имеется несколько экземпляров .... (если записи 8, 9, 10 и 11 имеют одинаковое значение, вы не можете получить t 10)
1

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

  • создавать представления с автоинкрементным столбцом int; скажем 'PagingHelperID'
  • пишите запросы типа: SELECT columns FROM viewname WHERE PagingHelperID BETWEEN startindex AND stopindex

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

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

  • 0
    Правильно. Я хочу избежать любого обнаружения базы данных.
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)

0

Я думаю, что для достижения этого каждый продукт следует за другим синтаксисом. Пожалуйста, найдите аналогичный вопрос ниже. Есть ли альтернатива ANSI SQL для ключевого слова LIMIT MYSQL?

Ещё вопросы

Сообщество Overcoder
Наверх
Меню