Форум программистов, компьютерный форум, киберфорум
Microsoft Access
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.74/152: Рейтинг темы: голосов - 152, средняя оценка - 4.74
3 / 3 / 0
Регистрация: 09.05.2009
Сообщений: 16
1

Нумерация строк запроса

03.07.2009, 00:03. Показов 30643. Ответов 29
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Как можно реализовать последовательную нумерацию строк запроса и вывести ее в первое поле строки?

Спасибо!
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
03.07.2009, 00:03
Ответы с готовыми решениями:

Нумерация дубликатов в колонке запроса
Добрый день, уже обыскал "весь" интернет. Нашёл несколько решений, но то ли они мне не подходят, то...

Нумерация строк
Доброй ночи всем, кто не спит! Подскажите, как сделать нумерацию строк, чтобы по умолчанию новая...

Нумерация строк в таблице
Просто есть пустая таблица и в ней одно поле и нет ни одной записи. Как можно быстро, т.е. с...

Нумерация строк в запросе
Добрый день, помогите запросом для нумерации строк в запросе, есть таблица с полем код все записи,...

29
10065 / 2622 / 84
Регистрация: 17.02.2009
Сообщений: 10,364
03.07.2009, 00:51 2
Постановка задачи 1. Запрос без полей MEMO и OLE.
Пусть имеется таблица (запрос) MyQuery с полем MyField. В запросе могут быть другие поля, допускающие предикат DISTINCT. MyQuery может быть отсортирован любым образом или вообще не отсортирован.
Требуется построить запрос, не меняющий порядка следования записей MyQuery, но добавляющий вычисляемое поле Num, представляющее номер строки MyQuery, начиная с 1.

Решение.
Текст запроса:
SQL
1
SELECT DISTINCT Numeration(MyField) AS Num, MyField FROM MyQuery WHERE Numeration() = 0;
В запросе используется функция Numeration. Вот ее описание:
Visual Basic
1
2
3
4
5
6
7
8
9
Public Function Numeration(Optional var) As Long
Static n As Long
If IsMissing(var) Then
n = 0
Else
n = n + 1
End If
Numeration = n
End Function
Комментарий 1. Запрос оптимизируется компилятором SQL. Поэтому значение функции в предложении WHERE, не зависящее от поля запроса , вычисляется только один раз. Этот вызов используется для установления начального значения счетчика.
Комментарий 2. Предикат DISTINCT используется для превращения динамического запроса в статический. (В динамическом запросе метод не работает.) Своей прямой роли предикат DISTINCT не играет, так как все строки результирующего запроса уникальны из-за нумерации. Однако он препятствует использованию в запросе полей MEMO и OLE.
Эти поля можно преобразовать в тип String, применяя функцию Mid(Field_MEMO_OLE,1). После чего конфликт исчезнет, но поля OLE потеряют свою функциональность. Если есть только поля MEMO, то такой подход применим.

Постановка задачи 2. В запросе допускаются любые поля.
Пусть имеется таблица (запрос) MyQuery с полем MyField. В запросе могут быть любые другие поля. MyQuery может быть отсортирован любым образом или вообще не отсортирован.

Требуется построить запрос, не меняющий порядка следования записей MyQuery, но добавляющий вычисляемое поле Num, представляющее номер строки MyQuery, начиная с 1.

Решение.
Текст запроса:
SQL
1
2
3
4
SELECT Numeration(MyField)/2 AS Num, FIRST(MyField) AS MyFieldFirst 
FROM MyQuery 
WHERE Numeration() = 0 
GROUP BY Numeration(MyField)/2;
Комментарий. Здесь запрос превращается в статический за счет применения группировки. Это снимает все требования с полей, но усложняет запрос и увеличивает время его исполнения. Для полей MEMO и OLE следует применять агрегатную функцию First или Last, для остальных достаточно указания группировки. Реально группировка также не проводится, так как первый уровень группировки (Numeration(MyField)/2)всегда дает одиночные записи.

О нумерованном динамическом запросе.
Улучшить метод получения нумерованного динамического запроса не удалось. Более того, разработать метод, нумерующий запрос со скоростью = C*n, по-видимому, невозможно. Поэтому для полноты привожу метод 3 из упомянутой выше статьи.
SQL
1
2
SELECT DCount("*", "MyQuery",КритерийСравнения) AS Num, MyField
FROM MyQuery ORDER BY MyField;
КритерийСравнения для чисел: "MyField <=" & MyField
КритерийСравнения для текста: "MyField <='" & MyField & "'"

Примечание.
Следует отметить, что реальная необходимость применения нумерованного динамического запроса возникает в только формах, предусматривающих корректировку данных. А в этом случае можно применить следующий прием:
- форму строим на нумерованном статическом запросе;
- корректировку проводим в свободном поле формы;
- после корректировки изменяем прямым доступом соответствующее поле в основной таблице;
- обновляем запрос в форме.

Примерно таким же образом можно ввести и новую запись. Все это, конечно, осложняет программирование, но резко увеличивает скорость исполнения. Разница в скоростях исполнения отчетливо видна уже на запросах в 1000 записей.

(с)копипащено
5
3 / 3 / 0
Регистрация: 09.05.2009
Сообщений: 16
03.07.2009, 01:34  [ТС] 3
Вот если взять ваш пример, пусть MyField=kod, MyQuery=1

То куда код

SQL
1
SELECT DISTINCT Numeration(kod) AS Num, kod FROM 1 WHERE Numeration() = 0;
вставлять, если у меня в режиме SQL уже есть запись типа

SQL
1
2
3
SELECT abiturients.kod, abiturients.surname_abiturient, abiturients.exam1_value
FROM abiturients
ORDER BY abiturients.exam1_value DESC;
0
10065 / 2622 / 84
Регистрация: 17.02.2009
Сообщений: 10,364
03.07.2009, 01:42 4
SQL
1
2
3
4
SELECT DISTINCT Numeration(abiturients.kod)  AS Num, abiturients.kod, abiturients.surname_abiturient, abiturients.exam1_value
FROM abiturients
WHERE Numeration() = 0
ORDER BY abiturients.exam1_value DESC;
0
3 / 3 / 0
Регистрация: 09.05.2009
Сообщений: 16
03.07.2009, 01:52  [ТС] 5
Цитата Сообщение от БурундукЪ Посмотреть сообщение
SQL
1
2
3
4
SELECT DISTINCT Numeration(abiturients.kod)  AS Num, abiturients.kod, abiturients.surname_abiturient, abiturients.exam1_value
FROM abiturients
WHERE Numeration() = 0
ORDER BY abiturients.exam1_value DESC;
Спасибо!
Появилась нумерация, но не решена основная задача - по идее нужно пронумеровать уже отсортированный по abiturients.exam1_value список.
0
10065 / 2622 / 84
Регистрация: 17.02.2009
Сообщений: 10,364
03.07.2009, 02:00 6
ну тогда делай сложный зыпрос. т.е.
на базе твоего запроса следующий запрос
SQL
1
2
3
SELECT DISTINCT Numeration(запрос1.kod)  AS Num, запрос1.kod, запрос1.surname_abiturient, запрос1.exam1_value
FROM запрос1
WHERE Numeration() = 0;
0
3 / 3 / 0
Регистрация: 09.05.2009
Сообщений: 16
03.07.2009, 02:16  [ТС] 7
Спасибо! Принцип понял. Получилось.
А что думаете про этот способ?
Q7: Как сымитировать счетчик в обычном запросе либо ленточной форме?

A1:

SQL
1
2
3
SELECT (SELECT SUM(1) FROM t AS p WHERE p.f<=p1.f), p1.f
FROM t AS p1
ORDER BY p1.f;
A2:
SQL
1
2
3
SELECT DCount("f", "t","f<=" & CStr(f)), f
FROM t
ORDER BY f;
Примечание 1. Поле f обязано быть уникальным.

Примечание 2. Способ 1 быстрее работает, но является необновляемым.

Примечание 3. Аналогичный вопрос в другом разделе FAQ:

Q.
Как организовать запрос к БД, чтобы он возвращал не только данные, но и порядковые номера строк в результирующем наборе ?

A.

Способов решить эту задачу несколько.
T-SQL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
use pubs
 
set nocount on
if exists (select * from sysobjects where type = 'U' and  name = 'test')
begin
    drop table test
end
/* создание таблицы для примера */
create table test
(
    id_test int identity not null,
    string char (7),
    constraint pk_test primary key (id_test)
)
/* установка флага для занесения с определенными ид. */
set identity_insert test on
/* занесение тестовых значений с произвольными ид. */
insert into test (id_test, string)
values (1,'string1')
insert into test (id_test, string)
values (4,'string2')
insert into test (id_test, string)
values (12,'string3')
insert into test (id_test, string)
values (17,'string4')
insert into test (id_test, string)
values (29,'string5')
insert into test (id_test, string)
values (31,'string6')
insert into test (id_test, string)
values (42,'string7')
insert into test (id_test, string)
values (45,'string8')
insert into test (id_test, string)
values (61,'string9')
/* отмена установки флага для занесения с определенными ид. */
set identity_insert test off
go
/* способ №1, создание проекции. */
if exists (select * from sysobjects where type = 'V' and name = 'ranked_table')
begin
    drop view ranked_table
end
go
create view ranked_table (rank, id_test, sting)
as
    select (
            select count(*) 
            from test as test_2
            where test_2.id_test <= test_1.id_test
        ) as rank,
        test_1.id_test,
        test_1.string
    from test as test_1
go
select * 
from ranked_table
order by rank
go
/* способ №2 стандартный SQL */
select count (test_2.id_test) as rank, test_1.id_test, test_1.string
from test as test_1 inner join test as test_2 on
    test_1.id_test >= test_2.id_test
group by test_1.id_test, test_1.string
order by rank
go
/* способ №3 стандартный SQL */
select test_3.rank, test_3.id_test, test_3.string
from (select test_1.id_test,
        test_1.string,
        (select count(*) 
            from test as test_2
            where test_2.id_test <= test_1.id_test
        ) as rank
    from test as test_1) as test_3
order by rank
go
/* способ №4, временная таблица с полем identity */
create table #rank_table
(
    rank int identity not null,
    id_test int null,
    string char (7),
    constraint pk_test primary key (rank)
)
go
insert into #rank_table (id_test, string)
select id_test, string
from test
order by id_test
select * from #rank_table
go
/* способ №5, переменная типа table с полем identity */
declare @rank_table table
(
    rank int identity not null,
    id_test int null,
    string char (7)
)
insert into @rank_table (id_test, string)
select id_test, string
from test
order by id_test
select * from @rank_table
go
/* способ №6, курсор */
declare @rank int,
    @id_test int,
    @string char (7)
declare rank_cursor cursor
for select id_test, string
    from test
    order by id_test
open rank_cursor
fetch next from rank_cursor into @id_test, @string
set @rank = 1
while (@@fetch_status <> -1)
begin
    select @rank, @id_test, @string
    set @rank = @rank + 1
    fetch next from rank_cursor into @id_test, @string
end
close rank_cursor
deallocate rank_cursor
/* результат всех примеров
rank id_test string
----------- ----------- -------
1 1 string1
2 4 string2
3 12 string3
4 17 string4
5 29 string5
6 31 string6
7 42 string7
8 45 string8
9 61 string9
*/



Соответственно нужно выбрать подходящий Вам.
Обратите внимание что пример №3 входит состовляющей частью в пример №1. Поэтому на примере №2 тоже можно построить проекцию. На мой взгляд, проекция на примере №2 наиболее оптимальна, вместе с примером №5. Выбор из №2 и №5 зависит от количества данных и пр.

Пример №5 будет работать только на SQL 2000. На SQL 2000 лучше использовать переменые типа table вместо временных таблиц, если это возможно.

Пример №6 на мой взгляд, наиболее неудачный и я привел его для общей эрудиции. Вроде привел всё что вспомнил. Если кто знает еще способы пишите.

есть ещё прикольный способ для sql2000 и выше.
Взято из методы "23 золотых совета по работе с MS SQL Serve" Шкрыль Андрея www.vr-online.ru:

T-SQL
1
2
3
4
5
6
7
8
9
10
11
12
declare i int
set i=0
 
select 0 as id, Name, Comm
into #temp
from MyTable
 
update #temp set @i=id=@i+1
 
select * from #temp
 
drop table #temp
A3: В новых версиях Аксесса у формы есть свойство CurrentRecord.
1
3 / 3 / 0
Регистрация: 25.06.2015
Сообщений: 50
04.11.2015, 16:02 8
Прошу помощи, сам не разобрался.
Создаю запрос, в котором нужно получить список литературных источников, расположенных в алфавитном порядке, и пронумерованных по возрастанию.
Есть таблица, в которой эти литературные источники расположены хаотично.
Для этого создаю запрос, в котором выбираются литературные источники и сортируются по алфавиту. И в отдельном поле присваиваются новые номера. Использую такой запрос:
SQL
1
2
3
SELECT DISTINCT Numeration(НазИст) AS НомСтр, СписокИст.НазИст, СписокИст.НТемы, СписокИст.[ОснД]
FROM СписокИст
WHERE (((Numeration())=0));
Запрос работает.
Но не могу его настроить, чтобы нумерация начиналась с произвольного значения (например, 2 или 3).
Если ставлю (((Numeration())=1)) - запрос никаких записей не показывает вообще, хотя их 59.
Прошу помочь настроить.
0
9108 / 6037 / 590
Регистрация: 27.03.2013
Сообщений: 19,813
04.11.2015, 16:17 9
Может попробовать, в запросе. в режиме конструктора. под нужным полем. в - Условие отбора , написать попроще, типа -
Numeration>=2
У вас же в условии отбора Numeration=0, соответственно ни чего и не покажет, т. к. номеров с 0 нет
0
Эксперт MS Access
26815 / 14494 / 3192
Регистрация: 28.04.2012
Сообщений: 15,782
04.11.2015, 16:53 10
Цитата Сообщение от karam_s Посмотреть сообщение
чтобы нумерация начиналась с произвольного значения (например, 2 или 3).
Прибавляете в запросе нужное значение к Numeration. Индексация начнется с числа на 1 больше указанного. Напишете Numeration(НазИст)+2, начнется с 3. И так далее.
SQL
1
2
3
SELECT DISTINCT Numeration(НазИст)+2 AS НомСтр, СписокИст.НазИст, СписокИст.НТемы, СписокИст.[ОснД]
FROM СписокИст
WHERE (((Numeration())=0));
1
3 / 3 / 0
Регистрация: 25.06.2015
Сообщений: 50
04.11.2015, 17:02 11
Numeration>=2 - не срабатывает - запрос никаких записей не показывает вообще.
Если Numeration=0, то запрос выдаёт все 59 записей.
Если Numeration>1, запрос выдаёт 0 записей.

Добавлено через 6 минут
mobile, УРА!!!
Это то, что надо!
Простите, если расшумелся
Numeration(НазИст)+2 - это то, чего мне не хватало, и что я не нашёл.
Спасибо, приятно иметь дело со спецами.
Выручили,
0
132 / 1 / 0
Регистрация: 22.02.2016
Сообщений: 19
18.04.2016, 20:08 12
SQL
1
2
3
4
SELECT DISTINCT Numeration([поле1])-1+[укажи начальный номер] AS НомСтр,
 яяя.поле1
FROM яяя
WHERE (((Numeration())=0));
1
132 / 1 / 0
Регистрация: 22.02.2016
Сообщений: 19
19.05.2016, 20:23 13
Здравствуйте. А можно как то отнумеровать сразу несколько фрагментов таблицы?
Чтобы каждый фрагмент - отдельно - своими номерами.

Например, фрагмент [ЗГ]="зг1" и фрагмент [ЗГ]="зг2"
получили номера, начиная от номеров [макс_ном] из справочника,
зг1 - от 100
зг2 - от 200
чтобы получилась нумерация как в третьей табличке:
запрос1
поле [ЗГ]поле [ном]
зг1 
зг1 
зг1 
зг2 
зг2 
зг2 
справочник
[ЗГ][макс_ном]
зг1100
зг2200
запрос1
поле [ЗГ]поле [ном]
зг1101
зг1102
зг1103
зг2201
зг2202
зг2203
0
9108 / 6037 / 590
Регистрация: 27.03.2013
Сообщений: 19,813
19.05.2016, 20:31 14
Слияние: [ЗГ]&[макс_ном]
0
Эксперт MS Access
2833 / 1375 / 215
Регистрация: 13.05.2011
Сообщений: 4,217
19.05.2016, 20:36 15
123uzer, Это можно сделать через условие (только надо понять его принцип). может так:
SQL
1
Новое:iif([макс_ном] BETWEEN 100 AND 199;"зг1";iif([макс_ном] BETWEEN 200 AND 299;"зг2";"зг3")
0
132 / 1 / 0
Регистрация: 22.02.2016
Сообщений: 19
19.05.2016, 20:59 16
Цитата Сообщение от PuhKMV Посмотреть сообщение
Слияние: [ЗГ]&[макс_ном]
В конструкторе запросов в поле ном вставил: обновить на Numeration([ном])+справочник![макс_ном] (справочник и запрос1 связаны один к одному).
Наверно после плюсика что то не то написал. Не сработало.
0
Эксперт MS Access
2833 / 1375 / 215
Регистрация: 13.05.2011
Сообщений: 4,217
19.05.2016, 21:09 17
123uzer, вы пример не делаете. Сделал сам (другим способом). Получились зг с номером первой цифры трехзначного числа (любого числа). Смотрите вложение (Запрос1).
SQL
1
2
SELECT Таблица2.макс_ном, "зг" & (LEFT([макс_ном],1)) AS ЗГ
FROM Таблица2;
Вложения
Тип файла: rar ЗГ.rar (16.1 Кб, 22 просмотров)
0
132 / 1 / 0
Регистрация: 22.02.2016
Сообщений: 19
19.05.2016, 22:07 18
Вячеслав Я
Ничего не понял, извините, последовательных номеров не увидел.
Справочник![макс_ном] - ключ. Между справочником и запрос1 связь по полю [ЗГ]

вот прикрепил. Вместо "запрос1" - табл1
Вложения
Тип файла: rar зг.rar (17.2 Кб, 14 просмотров)
0
132 / 1 / 0
Регистрация: 22.02.2016
Сообщений: 19
19.05.2016, 22:16 19
Цитата Сообщение от 123uzer Посмотреть сообщение
Справочник![макс_ном]
Извиняюсь, збрехал при копировании: на самом деле Справочник![зг] - ключик
0
Эксперт MS Access
2833 / 1375 / 215
Регистрация: 13.05.2011
Сообщений: 4,217
20.05.2016, 19:01 20
123uzer, не понял, что надо, но изменив схему данных получил что-то.

а по хорошему надо создать новую тему, т.к. ваша совсем не подходит под предложенную.
Вложения
Тип файла: rar ЗГ1.rar (20.5 Кб, 63 просмотров)
0
20.05.2016, 19:01
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
20.05.2016, 19:01
Помогаю со студенческими работами здесь

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

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

Нумерация строк в отчете
Доброго времени суток. Есть необходимость в отчете нумерацию строк весть снизу вверх, как это...

Нумерация строк в запросе
Всем привет! Подскажите, нужно чтобы нумерация была у таблицы, не получается, делаю так: ...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru