Порядковый номер строки в sql запросе
Подскажите, есть ли в sql команда, которая возвращает порядковый номер нужной строки из всего запроса? Допустим запрос вида SELECT * FROM table ORDER BY id ASC возвращает:
id|name -- ----- 1 |tenth 2 |first 3 |eighth . 8 |third 9 |ninth 10|second
Хотелось бы получить порядковый номер в выводе (именно номер, а не id) допустим, строки name == ‘third’ . Что-то вроде:
SELECT *** FROM table WHERE name = 'third' ORDER BY id ASC
Есть ли такая возможность?
Или необходимо делать весь запрос и уже из результата получать порядковый номер?
Как узнать номер строки в sql
← →
lmatveev ( 2003-10-30 13:35 ) [0]
Собственно subj. Когда делаешь запрос в Query Analyzer (или в ряде других средств), то в случае ошибки он выдает не только текст об ошибке, но и указывает в какой строке она произошла. Я тоже хочу это реализовать.
Для подключения я использую TADOConnection + OLE DB Provider for MS SQL Server.
В MSDN я вычитал, что такую инфу можно узнать, используя ODBC (использовать ODBC я принципиально не хочу, хотя подозреваю, что Query Analyzer именно так и работает) или через OLEDB.
Для того, чтобы узнать у OLEDB номер строки с ошибкой, ему вроде надо передать евойный интерфейс, вызвавший эту ошибку. А как его получить через ADOConnection?
Там же на MSDN нашел непонятную фразу: ADO does not support any provider-specific error interfaces, so SQL Server-specific error information such as the severity or state are available to ADO applications.
Короче, если кто знает как получить номер строки с ошибкой — очень прошу помочь
← →
lmatveev ( 2003-10-30 21:50 ) [1]
Неужто совсем никаких идей?
← →
Fay ( 2003-10-30 22:07 ) [2]
Ты в Delphi ведь знаешь, в какой строке Exception вылазит?
← →
Fay ( 2003-10-30 22:08 ) [3]
Намёк — в QA есть отладчик
← →
lmatveev ( 2003-10-30 23:26 ) [4]
Сильно сомневаюсь, что в QA есть отладчик, но даже если он и есть — информацию он с сервера берет. Так вот и вопрос в том как получить эту инфу.
А сравнение с Delphi мне кажется не совсем удачное — ведь в Delphi мне программу надо из под Delphi и запустить, чтобы строку с ошибкой узнать, а QA ведь сервер не запускает. Или я чего-то не понимаю?
← →
Mike_Goblin ( 2003-10-31 10:46 ) [5]
Идеи есть, одна из них посмотреть в сторону TAdOConnection.Errors
Возможно, нужная Вам информация там есть
Неплохо почтитать и это http://delphi.about.com/library/weekly/aa103001a.htm
← →
lmatveev ( 2003-10-31 13:57 ) [6]
В ADOConnection.Errors такой информации нет. Это я посмотрел в первую очередь. Ссылку щас попробую почитать.
Еще идеи?
← →
sniknik ( 2003-10-31 14:15 ) [7]
lmatveev (31.10.03 13:57) [6]
> В ADOConnection.Errors такой информации нет.
как так нет, есть, когда передается
вот выполни к примеру в запросе
print «строка 1»
print «строка 2» ошибка
получиш «Line 2» первым в эксепте
> Еще идеи?
анализатор запроса писать такойже как в Query Analyzer используется
(если ты имееш ввиду первую строку красным которую он выдает при выполнении)
← →
lmatveev ( 2003-10-31 15:12 ) [8]
В этом случае передается просто текст ошибки, который в ДАННОМ случае содержит номер строки. А QA всегда узнает номер строки. И узнает он это не из текста ошибки.
Дело в том, что QA использует для подключения к серверу ODBC драйвер, а через ODBC эту инфу получить можно. Я даже знаю как.
Но мне нужно узнать это через ADO+OLE DB Provider for SQL Server.
← →
sniknik ( 2003-10-31 15:17 ) [9]
> А QA всегда узнает номер строки.
не скажи
SELECT *
FROM
NothingTable —Несуществующая таблица
выдал
Server: Msg 208, Level 16, State 1, Line 1
Invalid object name «NothingTable».
← →
lmatveev ( 2003-10-31 15:31 ) [10]
Ну это уже проблема сервера — он видимо всю команду в батче воспринимает как одну строку. Видимо надо сказать > А QA ПОЧТИ всегда узнает номер строки, но не только когда ее номер содержится в тексте ошибки.
← →
sniknik ( 2003-10-31 15:45 ) [11]
тогда дай пример запроса который там распознается а ADO нет.
← →
sniknik ( 2003-10-31 15:48 ) [12]
заодно и метод как узнать через ODBC, у меня сообщения мало чем отличаются (в онформационной части)
на вышеприведенный запрос
ADO
Invalid object name «NothingTable»
ODBC
[Microsoft][ODBC SQL Server Driver][SQL Server]Invalid object name «NothingTable»
← →
Юрий Жуков ( 2003-10-31 18:05 ) [13]
Немного не по теме, но в Работающем приложении Delphi можно легко узнать в какой строке произошла ошибка. И компонет таких с десяток можно найти. Например
JCL (JEDI)
Eureka Exception log
← →
lmatveev ( 2003-10-31 19:53 ) [14]
> sniknik © (31.10.03 15:45) [11]
> тогда дай пример запроса который там распознается а ADO нет.
create proc test
as
select 1 from sysobjects
select 2 from syscomments
set ectvvuyv
go
Вот сообщение в QA:
Server: Msg 170, Level 15, State 1, Procedure test, Line 5
Line 5: Incorrect syntax near «ectvvuyv».
А вот все что можно вытянуть из ADO:
Description: «ectvvuyv» is not a recognized SET statement.; Error Number: -2147217900; SQL State: 42000; Source: Microsoft OLE DB Provider for SQL Server; Native Error: 195
> sniknik © (31.10.03 15:48) [12]
> заодно и метод как узнать через ODBC, у меня сообщения мало
> чем отличаются (в онформационной части)
В ODBC есть специальные API функции, которые возвращают детализацию об ошибке. Типа SQLGetDiagRec, SQLGetDiagield и т.п. В частности SQLGetDiagield содержит поля
SQL_DIAG_SS_LINE — номер строки с ошибкой (именно это мне и надо)
SQL_DIAG_SS_SEVERITY — значение Severity (тоже полезная информация при использоании RAISERROR
← →
lmatveev ( 2003-10-31 19:54 ) [15]
> lmatveev (31.10.03 19:53) [14]
> Типа SQLGetDiagRec, SQLGetDiagield и т.п. В частности SQLGetDiagield .
>
Здесь вместо SQLGetDiagield надо читать SQLGetDiagField
← →
lmatveev ( 2003-10-31 20:04 ) [16]
> Юрий Жуков (31.10.03 18:05) [13]
Никогда такими компонентами не пользовался, но думаю, чтобы узнать номер строки с ошибкой, они должны быть скомпилены вместе с приложением. Т.к. в работающем приложении, на чем бы оно не было написано НЕТ ИНФОРМАЦИИ о номерах строк исходников.
Возможно, добавив этот компонент на этапе компиляции они будут собирать информацию об исходниках или что-то в этом роде (типа Assert). В любом случае, наверное, можно будет в RunTime спросить у приложения в какой строке ошибка. Но при этом, в зависимости от настроения автора приложения, оно будет либо для всех ошибок выдавать эту информацию всегда, либо у приложения можно будет «спросить» детальную информацию об ошибке.
Раз уж MS SQL Server не выдает эту информацию в каждом сообщении, меня интересует как его об этом спросить. Ну то есть это немного сложнее, но общий смысл такой
← →
lmatveev ( 2003-10-31 20:34 ) [17]
Кстати, нашел в библиотеке sdiclnt.dll интерфейсы ISqlDebugger, ISqlDebugHost, ISqlDebugEvent, ISqlDebugEventCallback.
Похоже, что это интерфейсы, испорльзуемые QA при вызове команды Debug для хранимой процедуры. Может кто знает как их использовать?
← →
lmatveev ( 2003-11-01 03:19 ) [18]
Больше никто ничем не поможет?
← →
Suntechnic ( 2003-11-01 05:46 ) [19]
Вот здесь почитай подробнее:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/acdata/ac_8_con_05_4pv7.asp
Краткое резюме такое. ADO не даёт доступа к этой иформации, а вот в OLE DB через ISQLServerErrorInfo эту информацию достать можно.
Учитывая тот факт, что ADO это всего лишь надстройка над OLE DB, то, наверное, достать это всё-таки можно.
← →
lmatveev ( 2003-11-01 16:27 ) [20]
> Suntechnic © (01.11.03 05:46) [19]
Это я уже читал. Имеенно оттуда у меня цитата в первом сообщении. Вот вопрос то у меня как раз в том как через ADO достучаться до ISQLServerErrorInfo?
← →
sniknik ( 2003-11-01 19:45 ) [21]
lmatveev (31.10.03 19:53) [14]
попробовал пример, ADO выдает
Line 5: Incorrect syntax near «ectvvuyv»
т.е. пока мне кажется, инфа анологичная.
← →
sniknik ( 2003-11-01 19:47 ) [22]
> А вот все что можно вытянуть из ADO:
Description: «ectvvuyv» is not a recognized SET statement.; Error Number: -2147217900; SQL State: 42000; Source: Microsoft OLE DB Provider for SQL Server; Native Error: 195
как читаеш? я просто строку из ексепта (EOleException).
← →
sniknik ( 2003-11-01 19:51 ) [23]
да еще, то что в ODBC есть ODBC API функции я в курсе, интересно былобы с примером. (на предмет а действительно ли они возвращают? то что нужно)
подозрение есть что это не так, у него же не собственный «разборщик» синтаксиса, знает только то что ему в свою очередь SQL сервер дает.
← →
lmatveev ( 2003-11-01 21:17 ) [24]
> sniknik © (01.11.03 19:47) [22]
Я привел все поля, котрые есть в ADOConnection.Errors
При этом в EOLEException.Message у меня было только «ectvvuyv» is not a recognized SET statement.»
Можно узнать как ты получил «Line 5: Incorrect syntax near «ectvvuyv»»? Мне в принципе именно это и нужно.
> sniknik © (01.11.03 19:51) [23]
С ODBC я не разбирался, т.к. мне это принципиально не подходит, а ради спортивного интереса некогда.
← →
lmatveev ( 2003-11-01 21:32 ) [25]
Только что еще раз попробовал свой же пример и получил «Line 5: Incorrect syntax near «ectvvuyv»» !? Т.е. совсем не то, что в прошлый раз.
← →
sniknik ( 2003-11-02 00:38 ) [26]
вот я про тоже, вроде бы и разници никакой нет. (во всяком случае мне не удалось получить)
случайно не на разных машинах пробовал? в смысле может ADO старой версии действительно не так выдает(?)
← →
lmatveev ( 2003-11-02 21:15 ) [27]
Пробовал на разных машинах — результат везеде одинаковый. Я просто неудачный пример привел. Если в этот пример ниже добавить любые несколько строк, то и будет та ситуация, которую я пытаюсь разрулить. Вот 100% пример:
create proc test
as
select 1 from sysobjects
select 2 from syscomments
set ectvvuyv
12345
Т.е. после строки с ошибкой стоит еще хотя бы одна любая строка. Тогда мы имеем
В QA:
Server: Msg 195, Level 15, State 7, Procedure test, Line 6
«ectvvuyv» is not a recognized SET statement.
В ADO:
Description: «ectvvuyv» is not a recognized SET statement.
Error Number: -2147217900
SQL State: 42000
Source: Microsoft OLE DB Provider for SQL Server
Native Error: 195
Здесь ясно видно, что и там, и там номера строки в сообщении нет. Но QA пишет еще доп. информацию об ошибке, где содержится номер строки, severiry level и т.д.
Вот именно способ получения информации, которую QA пишет в первой строке меня так сильно и интересует.
Как узнать порядковый номер строки при сортировке?
Есть посты, у каждого поста есть рейтинг. Возможно ли узнать позицию поста в топе, зная только его рейтинг? Что-то вроде, отсортировать по рейтингу и выдернуть позицию в этой сортировке по id поста.
- Вопрос задан более трёх лет назад
- 3180 просмотров
Комментировать
Решения вопроса 1
Посчитать количество строк, рейтинг которых больше заданного (если в топе записи с самым большим рейтингом).
SELECT COUNT(*) FROM `posts` WHERE `rating` > ( SELECT `rating` FROM `posts` WHERE `id` = 42 )
Ответ написан более трёх лет назад
Комментировать
Нравится Комментировать
Ответы на вопрос 2
SET @Couner = 0;
SELECT @Counter := @Counter + 1, * FROM table;
А потом из получившийся таблицы выбираем позицию по рейтингу.

Ответ написан более трёх лет назад
Комментировать
Нравится Комментировать

Алексей Кулешов @GingerbreadMSK
Узнать позицию поста в топе, у которого рейтинг 100:
SELECT COUNT(*) FROM `posts` WHERE `rating` >= 100
Выдернуть пост по id:
SELECT* FROM `posts` WHERE `id` IN(SELECT COUNT(*) FROM `posts` WHERE `rating` >= 100)
MySQL номер строки
В SQL есть специальная функция вывода номеров строк в запросе ROW_NUMBER(). Но в его младшем брате MySQL нет такой функции. Единственный способ вывести номер строки в MySQL — использование переменной.
Поставим задачу: необходимо вывести имя пользователя, количество его очков и место в рейтинге по количеству этих очков. Т.е. такую таблицу:
| RANK | POINTS | NAME |
| 1 | 500 | Алексей |
| 2 | 300 | Сергей |
| 3 | 200 | Виталий |
Получать данные будем из таблицы истории получения очков, которая зовётся «history». Выглядит она так:
| DATE | POINTS | NAME |
| 26.03.2017 | 300 | Алексей |
| 16.08.2016 | 200 | Алексей |
| 11.01.2016 | 200 | Виталий |
| 28.12.2015 | 200 | Сергей |
| 14.07.2015 | 100 | Сергей |
Для начала получим суммы набранных очков, сгруппированные по именам пользователей и отсортированные по убыванию. Запрос будет выглядеть так:
SELECT SUM(POINTS) as ‘POINTS’, NAME FROM `history` GROUP BY NAME ORDER BY SUM(POINTS) DESC;
База вернёт следующую таблицу:
| POINTS | NAME |
| 500 | Алексей |
| 300 | Сергей |
| 200 | Виталий |
Отлично! Теперь надо пронумеровать строки, чтобы получить место пользователя в рейтинге. Алексей будет первым, Сергей — вторым, Виталий — третьим.
Нумеровка делается через переменную, добавляемую к выводу. Казалось бы, можно сделать всё просто:
SET @rank=0;
SELECT @rank:=@rank+1 AS ‘RANK’, SELECT SUM(POINTS) as ‘POINTS’, NAME FROM `history` GROUP BY NAME ORDER BY SUM(POINTS) DESC;
Но если сделать такой запрос, то результат будет плачевным. Назначение рейтинга произойдёт после группировки, но до сортировки ORDER BY SUM(POINTS). Выглядеть результат будет так:
| RANK | POINTS | NAME |
| 1 | 500 | Алексей |
| 3 | 300 | Сергей |
| 2 | 200 | Виталий |
Цифры ранга идут не по порядку: 1, 3, 2. Чтобы исправить положение необходимо добавлять столбец ранга после группировки и сортировки, в отдельном запросе. По логике, получается SELECT в SELECT. Синтаксис будет такой:
SET @rank=0;
SELECT @rank:=@rank+1 AS ‘RANK’, POINTS, NAME FROM
(SELECT SUM(POINTS) as ‘POINTS’, NAME
FROM `history` GROUP BY NAME ORDER BY SUM(POINTS) DESC) as t ;
Обратите внимание на окончание запроса. Без «as t;» написать запрос нельзя, иначе будет ошибка «Every derived table must have its own alias!«.
Результат такого запроса будет выглядеть как нормальная ранговая таблица. С правильным расположением цифр ранга:
| RANK | POINTS | NAME |
| 1 | 500 | Алексей |
| 2 | 300 | Сергей |
| 3 | 200 | Виталий |
Теперь усложним задачу. Получим содержание одной ячейки такой таблицы.
Представим, что нам нужно вывести номер ранга в личный кабинет пользователя. Чтобы Алексей видел в своём личном кабинете цифру «1», Сергей — «2», а Виталий — «3». Тогда запрос будет содержать SELECT внутри SELECT внутри SELECT. Вот так:
SET @rank=0;
SELECT RANK FROM
(SELECT @rank:=@rank+1 AS ‘RANK’, NAME FROM
(SELECT SUM(POINTS), NAME
FROM `history` GROUP BY NAME ORDER BY SUM(POINTS) DESC) as t1
) as t2
WHERE NAME = ‘Виталий’;
Обратите внимание на хвосты: «as t1», «as t2». Нужны разные псевдонимы, иначе будет ошибка «Every derived table must have its own alias!«.
P.S.
Конечно же, на реальном проекте такая таблица будет содержать id пользователя, а не его имя. Потому что в строке правды нет, а в числе есть
Публикации из этого раздела:
- На чём программируют программисты? — Какой язык программирования выучить первым? Этим вопросом задаются многие начинающие энтузиасты. Но .
- Как ускорить Windows — Сегодня меня попросили «посмотреть» компьютер, который тормозит. Это был первый раз за год, когда я .
- Шифрование папки — На всех переносимых устройствах (ноутбуках) использую полное шифрование диска (с шифрованием swap ра.
- Проблемы искусственного интеллекта — Прочитал предостережения Стивена Хокинга по поводу искусственного интеллекта. Думаю, в его словах ес.
- GTK. Включить тёмную тему — Чтобы включить тёмную тему оформления для приложений GTK, необходимо сделать несколько шагов.
- PHP заменить в строке — str_replace — Продолжаю рубрику шпаргалок PHP. В прошлый раз писал про обрезку строк. Вторая востребованная функци.
- Sony Xperia Ray. Где найти стиль? — Удивительно, почему производители мобильных телефонов перестали уделять внимание стилю, дизайну свои.
- Бэкап сайта по расписанию — В статье «MYSQL. Бэкап базы по расписанию» рассказывал как сделать резервную копию базы данных. Реко.
Добавить комментарий Отменить ответ
Свежие записи
- WordPress. Удалить изображения ко всем постам
- GTK. Включить тёмную тему
- APT. Обновить только один пакет
- Debian. Минимальная установка KDE
- systemd-resolved. Кеширование DNS запросов
- LUKS. Автомонтирование при загрузке
- Android. Отключение автозапуска программ
- Mysql. Загрузка таблицы из CSV
- Linux. Показать изображение в консоли
- Linux. Запустить Firefox в консоли
- Docker. Изменить время внутри контейнера
- Как удалить любое приложение на Android
Востребованное
- iptables. Набор правил
- Отключение ipv6
- Генератор паролей
- Генератор комментариев
- Лучшие названия статей
Рубрики
Комментарии
- Vlad к записи Linux и тачпад. Прикосновение для клика «tap to click»
- Константин к записи Отзыв о CS-Cart. Страшный сон для MySQL
- Maxsimus312 к записи Linux и тачпад. Прикосновение для клика «tap to click»
- Alex к записи Linux и тачпад. Прикосновение для клика «tap to click»
- Dmitry к записи Linux и тачпад. Прикосновение для клика «tap to click»
