2009-05-26 3 views
2

Нижеприведенный запрос является абсолютно функциональным и запрашивает одну таблицу, чтобы найти последние 50 имен пользователей, добавленных через последовательный столбец userid.Более элегантный SQL?

До сих пор логика: узнать наивысший идентификатор пользователя; вычесть 50 из этого; тянуть имена пользователей назад, где больше.

Однако, это не выглядит элегантно, и использует два подзапроса для достижения его цели:

SELECT username 
FROM table 
WHERE userid IN 
    (SELECT userid 
    FROM table 
    WHERE userid > 
    (SELECT MAX(userid) -50 
    FROM table)) 

Есть ли способ сделать это менее вложенной? Более эффективным? Более элегантный? Любая помощь будет высоко оценена, поскольку это не может быть лучшим способом!

Приветствия & большое спасибо
Али

+0

Я знаю SQL, но я не уверен в варианте Oracle.Вы посмотрели заявление TOP? В MS SQL (это то же самое) вы можете сделать; Выбрать Топ 50 имя пользователя из таблицы Заказать By UserId Desc; –

ответ

6

Ответы, являются в правильном направлении. Вы можете использовать ROWNUM для выбора результатов стиля TOP-N.

Будьте осторожны и обратите внимание, что rownum присваивается результатам запроса после предикации, но до ORDER BY. Попробуйте что-то вроде следующего:

SELECT username 
FROM 
    (SELECT username 
    FROM table 
    ORDER BY userid DESC) 
WHERE rownum <= 50 
+0

Следуя моему ответу, вы должны найти это очень полезным: http://www.oracle.com/technology/oramag/oracle/06-sep/o56asktom.html –

+0

Большое спасибо за хороший ответ и ссылку ChrisCM , Это хорошо работает. –

0

В зависимости от используемой базы данных, но попробовать что-то вроде этого:

оракул: выберите имя пользователя из таблицы, где ROWNUM < 50 заказ по идентификатору пользователя;

postgresql: выберите имя пользователя из таблицы order by userid limit 10;

+0

индекс rownum начинается с @ 1, а не 0, поэтому вам нужно меньше, чем равное, чтобы получить 50 строк. который возвращает только 49. –

+1

Решение Oracle не работает, потому что Oracle выполняет сначала, где rownum <50, только после этого он выполнит заказ. См. Также Эоин Кэмпбелл. – tuinstoel

1

Purely for aesthetic Я использую SQLinForm, который является апплетом Java, который очень хорошо форматирует ваш SQL. Это гибкий вариант с множеством опций.

+0

Кто бы ни проголосовал за это, он спросил об элегантности, и я заметил, что это чисто эстетическое; элегантный код должен читаться как в своем формате, так и в коде ... – joshcomley

0

как насчет:

SELECT username FROM table ORDER BY userid DESC LIMIT 50 
+0

Там будет причина для подзапросов. –

+1

Это MySql. –

+0

Причина для подзапроса заключается в том, что он может забрать последних 50 пользователей, а не всех пользователей с идентификатором пользователя> 50. ie userid> max (userid) -50 –

0

Если бы DateCreated поле в таблице пользователей, вы можете сделать запрос следующим образом:

SELECT TOP 50 username 
FROM table 
ORDER BY DateCreated DESC 
+1

Это синтаксис SQL Server –

+0

Прошу прощения, не видел тег oracle ... нет ли оракула эквивалент для предложения «TOP x»? – fretje

+0

Oracle использует «WHERE RowNum <= X»; RowNum является специальным столбцом Oracle – Andomar

2
SELECT * FROM (SELECT UserName FROM Table ORDER BY UserID DESC) 
WHERE RowNum <= 50 

... Я думаю. .. было некоторое время с тех пор, как я возился с Oracle.

Это примерно так же, как

SELECT Top 50 в SQLServer

и

SELECT ... LIMIT 50 в MySql

+0

@HankGay славное место. cheers –

2

Вы можете использовать ROW_NUMBER(), чтобы присвоить номер каждой строки, основываясь на его позиции в упорядоченном списке. Например, к числу строк, начиная с 1 для самого высокого идентификатору пользователя:

SELECT username 
FROM (
    SELECT 
     ROW_NUMBER() OVER (ORDER BY user_id DESC) AS RowNr, 
     * 
    FROM users 
) sub 
WHERE RowNr < 50 

В отличие от запроса в вопросе, это будет работать, если идент не последовательны.

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