Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Вот такой вопрос ! / 25 сообщений из 29, страница 1 из 2
02.07.2002, 10:56:25
    #32034669
Sanek
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вот такой вопрос !
Есть набор записей (неважно каких)
есть желание их получить , но в наборе записей - 1000 строк,а я хочу получить только с 100 по 200
т.е первые 100
select top 100
а остальные как ?
...
Рейтинг: 0 / 0
02.07.2002, 11:17:49
    #32034673
AnKa
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вот такой вопрос !
Начнем с того, что обязательно должен быть первичный ключ (если такового нет - введи IDENTITY поле).
Допустим, Field1 - первичный ключ, тогда


Код: plaintext
1.
2.
3.
4.
5.
SELECT TOP  200  *
FROM Table1 T1 
LEFT JOIN
(SELECT TOP  100 
 FROM Tab1) as T2 ON T1.Field1=T2.Field1
WHERE T2.Field1 IS NULL


здесь выбираются 200 начиная с 101
...
Рейтинг: 0 / 0
02.07.2002, 11:21:25
    #32034677
AnKa
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вот такой вопрос !
Блин, поправочка:

Код: plaintext
1.
2.
3.
4.
5.
SELECT TOP  200  T1.*
FROM Table1 T1 
LEFT JOIN
(SELECT TOP  100  *
 FROM Table1 ) as T2 ON T1.Field1=T2.Field1
WHERE T2.Field1 IS NULL
...
Рейтинг: 0 / 0
02.07.2002, 11:31:39
    #32034680
Rom
Rom
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вот такой вопрос !
2 АнКа - не работает такая штука ..
...
Рейтинг: 0 / 0
02.07.2002, 11:40:29
    #32034682
Rom
Rom
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вот такой вопрос !
Код: plaintext
1.
2.
3.
4.
5.
SELECT TOP  100  *
FROM Objs T1 
LEFT JOIN
(SELECT TOP  200  *
 FROM Objs ) as T2 ON T1.OID=T2.OID
WHERE T2.OID IS NULL

может так ?
...
Рейтинг: 0 / 0
02.07.2002, 11:42:26
    #32034683
SergSuper
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вот такой вопрос !
по-моему можно как-то так:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
SELECT TOP  100  id, name
  from(
    SELECT TOP  100  id, name
      from (
        SELECT TOP  200  *
          FROM sysobjects order by  id)  as t
      order by id desc) as t2
order by id


можно вставлять во временню таблицу с identity. В любом случае получается горбато
...
Рейтинг: 0 / 0
02.07.2002, 11:53:07
    #32034687
Sanek
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вот такой вопрос !
Спасибо !
Классная идея !
...
Рейтинг: 0 / 0
02.07.2002, 12:00:35
    #32034693
Rom
Rom
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вот такой вопрос !
кстати переправленный вариант от АнКа работает на УРА
...
Рейтинг: 0 / 0
02.07.2002, 12:09:45
    #32034696
Александр Степанов
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вот такой вопрос !
Код: plaintext
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.
create table #tab
(
	PK int identity( 1 , 1 ) not null,
	field varchar( 100 ) not null
)

insert into #tab(field) values('A')
insert into #tab(field) values('B')
insert into #tab(field) values('C')
insert into #tab(field) values('D')
insert into #tab(field) values('E')
insert into #tab(field) values('F')
insert into #tab(field) values('G')
insert into #tab(field) values('H')
insert into #tab(field) values('I')
insert into #tab(field) values('J')
insert into #tab(field) values('K')
insert into #tab(field) values('L')
insert into #tab(field) values('M')
insert into #tab(field) values('N')
insert into #tab(field) values('O')
insert into #tab(field) values('P')

 --select first 5 values
 
Select TOP  5  * from #tab order By PK

 --select second 5 values
 
Select TOP  5  
	t.* 
from 
	#tab t 
	inner join 
	(Select MAX(PK) PK from (Select TOP  5  * from #tab order By PK) t) tt 
		on t.PK>tt.PK order By t.PK

 --select third 5 values
 
Select TOP  5  
	t.* 
from 
	#tab t 
	inner join 
	(Select MAX(PK) PK from (Select TOP  10  * from #tab order By PK) t) tt 
		on t.PK>tt.PK order By t.PK


drop table #tab


Поле, по которому осуществляется сортировка, должно быть уникальным.
...
Рейтинг: 0 / 0
02.07.2002, 18:55:38
    #32034810
SM
SM
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вот такой вопрос !
А если усложнить задачу? Получить N ную порцию из M записей? Причем N и M - задаются пользователем? Эдакий пэйджинг ?
...
Рейтинг: 0 / 0
02.07.2002, 22:23:03
    #32034821
Cat2
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вот такой вопрос !
Я тут не досуге решил FAQ по этому вопросу написать, доделать полностью не успел, но вот что есть. Выношу на обсуждение, благо есть повод.

Glory, ау! У Вас была сделано такая штука, но я теперь хоть убей не могу ее найти.
===========================================
Создана тестовая таблица на 10000 записей.

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
CREATE TABLE [dbo].[NTable] (
	[RowID] [int] IDENTITY ( 1 ,  1 ) NOT NULL ,
	[DDate] [datetime] NULL ,
	[NDate] [float] NULL 
)
GO

ALTER TABLE [dbo].[NTable] WITH NOCHECK ADD 
	CONSTRAINT [PK_rowcount] PRIMARY KEY  CLUSTERED 
	(
		[RowID]
	)  ON [PRIMARY] 
GO

 CREATE  INDEX [IX_NTable] ON [dbo].[NTable]([NDate]) ON [PRIMARY]
GO

С полями RowID и DDаte все ясно, про поле NDate - несколько попозже.

Задача. Выделить m записей начиная с позиции n.
Записи должны быть отсортированы по обратному порядку даты создания (DDate), то есть первыми должны быть самые "свежие"


Созданы две хранимые процедуры. Параметр @rfirst - номер первой записи, @rcount - количество возвращаемых записей.


Способ 1. Обрезание результатов

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
CREATE PROCEDURE rn_top @rfirst int, @rcount int AS
set @rfirst=@rfirst+@rcount

SET ROWCOUNT @rfirst
select DDate,RowID into #temp from NTable
order by DDate desc

SET ROWCOUNT @rcount
select DDate,RowID from #temp
SET ROWCOUNT  0 

Способ 2. Усовершенствованное обрезание результатов
Скорость этого способа выше, так как
используется индекс по полю NDate, которое было заполнено следующим образом:
Код: plaintext
1.
Update NTable
set NDate = - convert(float,DDate)

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

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
CREATE PROCEDURE rnNd_top @rfirst int, @rcount int AS
set @rfirst=@rfirst+@rcount

SET ROWCOUNT @rfirst
select DDate,RowID into #temp from NTable
order by NDate

SET ROWCOUNT @rcount
select DDate,RowID from #temp
SET ROWCOUNT  0 
...
Рейтинг: 0 / 0
03.07.2002, 00:23:08
    #32034825
SM
SM
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вот такой вопрос !
а если сортировка может быть какой угодно - по возрастанию и убыванию, причем по любому из полей базового запроса ?
...
Рейтинг: 0 / 0
03.07.2002, 07:09:22
    #32034838
Cat2
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вот такой вопрос !
А кто мешает поставить свой ORDER BY c любыми полями и их комбинациями? В способе 1 это не проблема. Для разных комбинаций полей можно наделать разных процедур.

Другое дело способ 2. Он конечно более специфический и требует создания дополнительного поля (полей) обратной сортировки, что легко делается только для числовых данных (включая Datetime). Приведен он главным образом для того, что бы показать, как правильно созданный индекс может увеличить скорость обработки.
Если бы в задаче не надо было бы сортировать даты по убыванию, то нужно было бы просто сделать индекс по DDate.

А вообще-то данная задача (возвращение N записей, начиная с M-той) порочна по своей сути. Пользователю возвращается не то, что ему нужно, а просто куча информации - пускай сам ищет что ему надо, а мы (разработчики), умываем руки. С этим можно смириться только в интернет-приложениях, типа форума, гостевой книги или чата.
...
Рейтинг: 0 / 0
03.07.2002, 09:21:15
    #32034854
Sanek
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вот такой вопрос !
Погодите !
Либо я не догоняю, либо все проще ...
если есть таблица (в примере от Cat2)
известна запись с которой надо начинать ... и кол-во строк ... то тогда можно зацепиться за поле RowID
т.е.

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
CREATE PROCEDURE rnNd_top @rfirst int, @rcount int AS

SET ROWCOUNT @rcount 

select DDate,RowID 
where RowID < @rfirst 
order by NDate

SET ROWCOUNT  0 


Или я неправ ...
PS.
Какя разница (следить за номером строки или за ее кодом ?)
...
Рейтинг: 0 / 0
03.07.2002, 12:45:55
    #32034915
Glory
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вот такой вопрос !
2 Cat2
Glory, ау! У Вас была сделано такая штука, но я теперь хоть убей не могу ее найти.

Да где-то это затерялось при переезде форума. Если только админ сообщит номера топиков....

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

2Sanek
Какя разница (следить за номером строки или за ее кодом ?)

А если в RowID имеются "пробелы" ?
...
Рейтинг: 0 / 0
03.07.2002, 12:52:24
    #32034918
Sanek
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вот такой вопрос !
>Glory
в примере от Cat2
написанно на чистом SQL
Код: plaintext
[RowID] [int] IDENTITY ( 1 ,  1 ) 

, что в моем понимании есть автоинкрементное поле, т.е. Integer
Про пробелы в этом типе данных ничего не сказано , да и в номере строки пробел тоже наврядли появиться .. :)
...
Рейтинг: 0 / 0
03.07.2002, 13:06:19
    #32034925
fima
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вот такой вопрос !
Я сегодня отвечал на похожий вопрос о нумерации. Для динамического количества выводимых строк, по моему их надо считать. /topic/9523 здесь примеры какие я знаю для нумерации строк, чуть изменить под данную задачу не трудно. Если поможет буду рад...
...
Рейтинг: 0 / 0
03.07.2002, 13:06:38
    #32034926
Glory
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вот такой вопрос !
"Пробелы" в поле identity могут получится при нормальной работе, например, в результате отакта транзакции
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
truncate table ntable
go
insert ntable values(GETDATE(),  1 )
select IDENT_CURRENT('ntable')
go
begin transaction
insert ntable values(GETDATE(),  1 )
rollback transaction
go
insert ntable values(GETDATE(),  1 )
select IDENT_CURRENT('ntable')
select * from ntable
go
...
Рейтинг: 0 / 0
03.07.2002, 13:19:40
    #32034929
Sanek
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вот такой вопрос !
прошу прощения !
Понял !
Осознал ... и т.п.

Нашел ошибку и исправил :
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
CREATE PROCEDURE rnNd_top @rfirst int, @rcount int AS

SET ROWCOUNT @rcount 

select DDate,RowID 
where RowID > @rfirst 
order by NDate

SET ROWCOUNT  0 



В этом случае мало интересно пропуски индекса ... :)
...
Рейтинг: 0 / 0
03.07.2002, 14:00:06
    #32034936
Glory
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вот такой вопрос !
2 Cat2, Sanek

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

Для большего правдоподобия я заполнил тестовую таблицу произвольными значениями RowId

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
truncate table ntable
go
SET IDENTITY_INSERT ntable ON
go
declare @i int, @j int
set @i =  10000 

while @i >  0 
begin
	set @i = @i -  1 
	if (@i %  3 ) =  0  
	begin
		set @j = CAST(RAND()* 100000  AS int)
		while @j <=  10000  or exists(select * from ntable where rowid = @j) set @j = CAST(RAND()* 100000  AS int)
	end
	else set @j = @i
	insert ntable(rowid, ddate) values(@j, DATEADD(dd, CAST(RAND()* 1000  AS int), GETDATE()))

end
go
SET IDENTITY_INSERT ntable OFF
go
Update NTable set NDate = - convert(float,DDate)
go
...
Рейтинг: 0 / 0
03.07.2002, 14:19:01
    #32034939
Sanek
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вот такой вопрос !
>Glory

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
 Declare @RowNo integer,@RowCount integer
SET @RowCount =  10 
SET ROWCOUNT @RowCount
SET RowNo =  0 

SELECT *
  FROM ntable
WHERE RowID > @RowNo 
order by RowID

SET RowNo =  10 

SELECT *
  FROM ntable
WHERE RowID > @RowNo 
order by RowID

SET ROWCOUNT  0 

Попробовал совместно с твоим запросом и все работает нормально , только :) сортировку изменил с NDate на RowID
...
Рейтинг: 0 / 0
03.07.2002, 20:03:18
    #32035020
Cat2
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вот такой вопрос !
Данные примеры показывают способ работы с полем DDate, котрый не коррелирует с кластерным индексом по RowID. Такая корреляция обычно бывает, например, при оформлении каких-то докментов.

Значения DDate могут перманентно менятся. A'la время последнего ответа на вопрос в форуме, где RowID означает ID темы, a DDate обновляет тригер последнего постинга в эту тему.

Все, что выше этой строки, написано до полного разбора полетов.
Ну дела!!! Ну M$ наоптимизировал!
После издевательств над базой по методу Glory все любовно выписанное рухнуло. Плевал оказывается MS SQL на всякие там ордер бай при вставке во временные таблицы. И моя вера в физическое расположение записей по кластерному индексу сильно подорвана. Может быть по этому поводу выскажется кто-нибудь из DBA? У меня такое подозрение, что после столь крутых изменений первичного ключа таблицу надо как-то оптимизировать.

"Орешек знаний тверд, но все же мы не привыкли отступать..."

А как Вам такое извращение?

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
CREATE PROCEDURE rnd_top @rfirst int, @rcount int AS
set @rfirst=@rfirst+@rcount

SET ROWCOUNT @rfirst
select DDate,RowID  into #temp from NTable
order by DDate desc

SET ROWCOUNT @rcount
select  DDate,RowID into #temp2 from #temp
order by DDate 

select  DDate,RowID from #temp2
order by DDate desc
SET ROWCOUNT  0 


С полем NDate ничего пока не придумал. Не работает ни под каким соусом.
...
Рейтинг: 0 / 0
03.07.2002, 20:34:39
    #32035024
Vit!
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вот такой вопрос !
Код: plaintext
1.
select top  100  * from 
  (Select top  200  * From MyTable) as T
...
Рейтинг: 0 / 0
03.07.2002, 20:46:33
    #32035027
Cat2
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вот такой вопрос !
Re Vit!

В обороте TOP нельзя использовать переменные.
Вы не обратили внимание, что надо сортировать по возрастанию даты, а не по кластерному индексу.

Конечно, можно использовать динамический SQL, но при более сложных выборках это будет тормозить.

Если Вам не лень, попробуйте свой пример на вышеприведенной тестовой таблице, обработаной по методу GLory.
Мне честно говоря, сегодня лень.

Кстати, на моей памяти, это не то тридцатое, не то сороковое предложение данного способа. Наверное, что-то тут не то, если он так и не стал каноническим.
...
Рейтинг: 0 / 0
03.07.2002, 23:17:43
    #32035036
Cat2
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вот такой вопрос !
Я в постинге от 20020703 20:03 несколько запутанно выразился. Данная задача призвана решить некоррелированные с PRIMARY выборки. Разговор про документы является примером коррелированных данных.
...
Рейтинг: 0 / 0
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Вот такой вопрос ! / 25 сообщений из 29, страница 1 из 2
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]