Имя: Пароль:
1C
1С v8
запрос в цикле
,
0 Domanoff26
 
06.12.12
13:04
Хотел отбирать кусками данные по примеру выбрать первые 30 и так в цикле по всем данным, как это реализовать проще всего? создавать номера строк путем соединения таблица самой с собой не получится - большущая и сложная таблица слишком...
1 cw014
 
06.12.12
13:06
Не переварил задачу
2 Затейник
 
06.12.12
13:07
А если в запросе будет миллион строк? а 10 миллионов? Такой цикл повесится на ближайшей березе
3 МихаилМ
 
06.12.12
13:10
недавно была тема

v8: как в запросе пронумеровать строки результата?

автора поспрашайте
4 Domanoff26
 
06.12.12
13:10
(2)огромный результат запроса тоже будет не в восторге
5 МихаилМ
 
06.12.12
13:12
+(3)
иногда лучше объяснить проблему
чем искать возможное решение. тк могут быть и другие решения
6 acsent
 
06.12.12
13:14
чтобы выбирать ПЕРВЫЕ Х, нужен уникальный ключ
7 Domanoff26
 
06.12.12
13:16
(5) проблема в принципе решилась, не очень хорошо но да, но вот идея не выходит из головы, ведь по любому это нужно иногда, ну вот представьте запрос милионом строк, и их нужно по странично выводить по кликам (на сайт например), нумерация строк ведь тоже не хороший метод - все равно кадлый раз отбираются все строки...
8 Domanoff26
 
06.12.12
13:17
есть еще идея уже отобранные помещать вв времен табл, а потом ее исключать из результата, но опять же скорость работы?
9 Rovan
 
гуру
06.12.12
13:25
(0) зря ты так.... а если между запросами произошла запись в базу - что тогда ?
10 Undefined vs NULL
 
06.12.12
13:26
(7) кому нужны миллионы строк?
11 МихаилМ
 
06.12.12
13:27
(7)
если можно построить индекс можно не уникальный те структурировать данные.

то  можно получить оценку (распределение) записей
на основе распределения отбирать по границам ключам индекса.

примерно подходящую порцию данных.
12 Domanoff26
 
06.12.12
13:28
(9) вот это довод конкретный
(11) можно как нить попроще объяснить
13 МихаилМ
 
06.12.12
13:31
14 МихаилМ
 
06.12.12
15:55
(12)

если есть первичный ключ то все еще проще
и начало выборки (ключ первой записи ) известен то

все просто : select top N from table
            order by строго все поля индекса

долее листаем точное кол-во записей

select top N from table


where

значение ключа больше заданного,  
подсмотрите в мс скл профайлере, как 1с8 пролистывает РС
лень сюда писать
order by СТРОГО все К поля индекса


теперь вариант листания из (11)
он может подойти для снижения нагрузки либо ускорения,

делается  оценка плотности записей
предварительным запросом

запрос отработает быстро, т.к. кол-во записей хранится в узлах
дерева индекса.


по на основании оценки рассчитывается  граница (ключ) каждого следующего интервала. метод не стабильный. особенно для таблиц, в которые происходит интенсивная вставка либо удаление.

но в среднем производительней простого классического  
select top для физических таблиц особенно для  субд блокировочников

неудобство обоих в громоздкости условий в тексте запроса.
15 МихаилМ
 
06.12.12
16:05
(14)

вот упрощеный вариант запроса к рс

exec sp_executesql N'SELECT TOP 40
_InfoRg5531_IR._Fld5532_TYPE AS _A1_TYPE,
_InfoRg5531_IR._Fld5532_RTRef AS _A1_RTRef,
_InfoRg5531_IR._Fld5532_RRRef AS _A1_RRRef,
_InfoRg5531_IR._Fld5533RRef AS _A2RRef,
FROM
_InfoRg5531 _InfoRg5531_IR WITH(NOLOCK)
WHERE
_InfoRg5531_IR._Fld5532_RRRef = P1 AND _InfoRg5531_IR._Fld5532_RTRef = @P2 AND _InfoRg5531_IR._Fld5532_TYPE = @P3 AND _InfoRg5531_IR._Fld5533RRef >= @P4 OR
_InfoRg5531_IR._Fld5532_RRRef > P1 AND _InfoRg5531_IR._Fld5532_RTRef = @P2 AND _InfoRg5531_IR._Fld5532_TYPE = @P3 OR
_InfoRg5531_IR._Fld5532_RTRef > @P2 AND _InfoRg5531_IR._Fld5532_TYPE = @P3 OR
_InfoRg5531_IR._Fld5532_TYPE > @P3
ORDER BY
_InfoRg5531_IR._Fld5532_TYPE,
_InfoRg5531_IR._Fld5532_RTRef,
_InfoRg5531_IR._Fld5532_RRRef,
_InfoRg5531_IR._Fld5533RRef', N'P1 varbinary(16),@P2 varbinary(4),@P3 varbinary(1),@P4 varbinary(16)', 0x80A4001320B6885711DD25D49C350DC0, 0x0000003A, 0x08, 0x8A216A2796765189458DC07314ED51E7
16 organizm
 
06.12.12
16:11
можно во временную таблицу на сервере выбрать, а затем в цикле уже выбирать из нее. очень нормально по скорости получается для миллионных выборок.
17 Serginio1
 
06.12.12
16:16
Делаешь Запрос
Выбрать первые 30
ORDER BY поле1,поле2,поле3

поле1,поле2,поле3 должно быть уникальной комбинацией

следующие запросы

Выбрать первые 30
Where поле1>=@поле1 и поле2>=@поле2 и поле3>@поле3
ORDER BY поле1,поле2,поле3

поле1,поле2,поле3 должно быть уникальной комбинацией
@поле1,@поле2,@поле3 значение полей из последней строки выборки
18 МихаилМ
 
06.12.12
16:16
+ (15)

сделал выжимку для более легкого понимания условия .
аналогично для верхней границы
WHERE
поле1 > @P3
OR
поле2 > @P2 AND поле1 = @P3
OR
поле3 > P1 AND поле2 = @P2 AND поле1 = @P3
OR
поле3 = P1 AND поле2 = @P2 AND поле1 = @P3 AND поле4 >= @P4

ORDER BY
поле1,
поле2,
поле3,
поле4
19 МихаилМ
 
06.12.12
16:18
(17)
я когдато тоже так думал. это ошибочное условие.
20 Serginio1
 
06.12.12
16:27
(19) Почему? Если поле3 является уникальным?
А вот так

Where
 Выбор Когда
(поле1=@поле1 и поле2=@поле2) Тогда
поле3>@поле3
Иначе
(поле1>=@поле1 и поле2>=@поле2)
     
КонецЕсли
21 samozvanec
 
06.12.12
16:29
(0)зачем?
22 МихаилМ
 
06.12.12
16:34
(20)
если поле3 является уникальным то понему нужно создать индекс
и листать с его помощью.  

расматривается случай составных индексов. не обязательно уникальных.

в Where использовать case (выбор) - не реляционный подход:
оптимизатор не сможет использовать индексы.
23 Serginio1
 
06.12.12
16:34
Вот правильно
Where
 Выбор
Когда
(поле1=@поле1 и поле2=@поле2) Тогда
поле3>@поле3
Когда поле1=@поле1 Тогда
  поле2>@поле2
Иначе
(поле1>@поле1)
     
КонецЕсли
24 Serginio1
 
06.12.12
16:35
(22) Ну а что делать то. Надо посмотреть, что там с туплами. На Шарпе лего реализовать функцию сравнения
25 Serginio1
 
06.12.12
16:43
Ну да функция сравнения должна быть такая

Выбор Когда поле1<@поле1 Тогда
ложь
Выбор Когда поле1=@поле1 и поле2<@поле2 Тогда
Ложь
Выбор Когда поле1=@поле1 и поле2=@поле2 Тогда
поле3>@поле3
иначе
истина
истина
Конец
26 МихаилМ
 
06.12.12
16:47
(23)
это извращенный вариант  (18)
не уверен, что оптимизатор запросов его павильлно
интерпретирует.

проверять лень.

не знаю что такое туплы и шарп здесь не пригодится.
27 Serginio1
 
06.12.12
16:51
А так?
USE AdventureWorks2012;
GO
WITH OrderedOrders AS
(
   SELECT SalesOrderID, OrderDate,
   ROW_NUMBER() OVER (ORDER BY OrderDate) AS RowNumber
   FROM Sales.SalesOrderHeader
)
SELECT SalesOrderID, OrderDate, RowNumber  
FROM OrderedOrders
WHERE RowNumber BETWEEN 50 AND 60;
28 Serginio1
 
06.12.12
16:52
(26) Ну тогда делай через Union.
29 Serginio1
 
06.12.12
17:01
Другой вариант делать несколько запросов

Выбрать первые 30
Where поле1=@поле1 и поле2=@поле2 и поле3>@поле3
ORDER BY поле1,поле2,поле3


Выбрать первые 30-Колисество в первой выборке
Where поле1=@поле1 и поле2>@поле2
ORDER BY поле1,поле2,поле3

Выбрать первые 30-(Колисество во первой выборке) - -(Колисество во второй выборке)
Where поле1>@поле1
ORDER BY поле1,поле2,поле3
30 Serginio1
 
07.12.12
11:09
(18) Прошу прощения чего то меня вчера переклинило конечно же
Выбрать первые 30
Where (поле1=@поле1 и поле2=@поле2 и поле3>@поле3)
       или
     (поле1=@поле1 и поле2>@поле2)
     или поле1>@поле1
ORDER BY поле1,поле2,поле3