Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Transact-SQL @CURSOR / 25 сообщений из 36, страница 1 из 2
08.01.2018, 21:04
    #39580689
peskauskas
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Transact-SQL @CURSOR
Господа, доброго времени суток!
Мне нужна ваша помощь!

задача:
есть 2 таблицы

1. Unit (ключевые поля)
id int (айди юнита)
ShortName VARCHAR(10)

и

2. Position (ключевые поля)
MngUnit int not NULL
TimeStamp datatime
IPO int (два значения 0 или 1)

у каждого юнита есть трекинг по GPS соотв долгота и широта и
время контрольной точки (поле TimeStamp), так же есть статус онлайн или оффлайн (IPO)
нужно назначить курсор с перебором ВСЕХ айди начиная с 1 и по FEENCH=0 таким образом, чтобы:
1. найти первую строку(первое вхождение) где юнит оффлайн (IPO = 0) и назначить переменной @TP(--TimePast) значение времени TimeStamp.
2. далее если
а. следующая строка оффлайн (IPO = 0), то вычленить разницу времени таким образом
(@TR(--TimeReal) = TimeStamp) - @TP = @TS (--TimeSum)
б. следующая строка онлайн (IPO = 1) И уравнение ИСТИНА ((@TR(--TimeReal) = TimeStamp) - @TP > 15 (--seconds)) ТО ((@TR(--TimeReal) = TimeStamp) - @TP = @TS), ЕСЛИ разница менее 15 секунд, то (@TR = @TP ) или просто перейти на сл строку безобновлений переменных.

когда кончатся строки по данному айди юнита, нужно увидеть суммарное время оффлайна по выше написанным критериям.

и соответственно внести их в таблицу TimeOfflineUnit
поле unit_id = u.ShortName и TimeOfflane = @TS (для каждого юнита свое значение)

при переходе на сл айди соотв переменные @TS = 0, @TP = поля TimeStamp, первой строке с критерием поля IPO = 0

у меня пока (5-е сутки) получилось нечто не очень понятное...
но все же.

переменные:
@TP -- Прошлое время, поле TimeStamp, пред-идущая строка этого айди
@TR -- Реальное время, поле TimeStamp, текущая строка этого айди
@TS -- Суммарное время, которое пойдет в итоговую таблицу вывода.
@UID -- Айди юнита на текущий период поиска (от 1 и до n..)

должны быть еще переменные, но какие точно пока не могу понять

в итога должно получиться что то вроде прикрепил файл. 1 и 2 представлены, 3 итог.

-----------------------------------------------------------------------------

DECLARE @IDch int = 2104 --для теста взял конкретный айди

SELECT u.ShortName as Unit_ID, p.TimeStamp, p.IPO
from [dbo].[Unit] u INNER JOIN [dbo].[Position] p
ON p.MngUnit = u.id
WHERE u.id = @IDch

-----------------------------------------------------------------------------

в начале должно быть что то вида
CREATE TABLE TimeOfflineUnit
id int
Unit_Id VARCHAR (10)
TimeOffline time(2)
primary key ('id')

в конце дроп.
БУДУ ПРИМНОЖЕСТВЕННО благодарен за помощь в разборке или написания курсора.
...
Рейтинг: 0 / 0
08.01.2018, 21:46
    #39580708
peskauskas
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Transact-SQL @CURSOR
...
Рейтинг: 0 / 0
09.01.2018, 08:17
    #39580809
iii2
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Transact-SQL @CURSOR
Курсор то тут нафига? чтобы дольше работало?
Всё двумя запросами решается (т.к. 2 таблицы апдейтить).
...
Рейтинг: 0 / 0
09.01.2018, 12:18
    #39580955
peskauskas
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Transact-SQL @CURSOR
iii2,

Будьте добры, подсказать, как это сделать правильно !?
...
Рейтинг: 0 / 0
09.01.2018, 14:54
    #39581090
iii2
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Transact-SQL @CURSOR
Какая версия сервера?
...
Рейтинг: 0 / 0
09.01.2018, 15:47
    #39581125
iiyama
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Transact-SQL @CURSOR
peskauskas,

погуглите => задача поиска островов
...
Рейтинг: 0 / 0
09.01.2018, 18:43
    #39581249
Руслан Дамирович
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Transact-SQL @CURSOR
Просьба убрать от экранов детей, беременных и кормящих женщин, а также психически нестабильных личностей
Код: 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.
DECLARE @data TABLE ( [id] INT, [time] DATETIME2(0), [ipo] TINYINT )
INSERT INTO @data VALUES 
( 2344, '2017-05-01T12:10:08', 1 ),
( 2464, '2017-05-01T12:10:11', 1 ),
( 2304, '2017-05-01T12:10:13', 0 ),
( 2384, '2017-05-01T12:10:16', 1 ),
( 2344, '2017-05-01T12:10:18', 0 ),
( 2344, '2017-05-01T12:10:19', 0 ),
( 2344, '2017-05-01T12:10:20', 1 ),
( 2224, '2017-05-01T12:10:21', 0 )
;
/*Острова. Детская задачка по определению границы изменения значений*/
WITH
t0 AS (
  /* Выполняем свертку значений */
  /* Марлезонский балет. Часть первая */
  SELECT
    *,
    [gr] = ROW_NUMBER() OVER ( PARTITION BY [id] ORDER BY [time] )
         - ROW_NUMBER() OVER ( PARTITION BY [id], [ipo] ORDER BY [time] )
  FROM
    @data
),
t1 AS (
  /* Марлезонский балет. Часть вторая */
  SELECT
    [id],
    [time] = MIN( [time] ),
    [ipo]
  FROM
    t0
  GROUP BY
    [id],
    [ipo],
    [gr]
),
t2 AS (
  /* Ранжируем свертку по дате */
  /* Все это не нужно, если есть LAG/LEAD, но их у меня нет */
  SELECT
    [id],
    [time],
    [ipo],
    [rn] = ROW_NUMBER() OVER ( PARTITION BY [id] ORDER BY [time] )
  FROM
    t1
),
t3 AS (
  /* Здесь мы считаем, что первое считанное значение распространяется на весь день с его начала */
  SELECT
    [id],
    [time],
    [ipo],
    [rn] = [rn] + 1
  FROM
    t2
  UNION ALL
  SELECT
    [id],
    [time] = CONVERT( DATE, [time] ),
    [ipo],
    [rn] = 1
  FROM
    t2
  WHERE
    [rn] = 1
),
t4 AS (
  /* Здесь мы считаем, что последнее считанное значение распространяется на весь день до его окончания */
  SELECT
    c.[id],
    c.[ipo],
    [duration] = SUM( DATEDIFF( S, c.[time], ISNULL( n.[time], DATEADD( DAY, 1, CONVERT( DATE, c.[time] ) ) ) ) )
  FROM
    t3 c
    LEFT JOIN t3 n ON (
          n.[id] = c.[id]
      AND n.[rn] = c.[rn] + 1 )
  GROUP BY
    c.[id],
    c.[ipo]
)
/* Отбираем записи, у которых был офф-лайн */
SELECT
  *
FROM
  t4
WHERE
  [ipo] = 0
;


...
Рейтинг: 0 / 0
09.01.2018, 19:21
    #39581258
peskauskas
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Transact-SQL @CURSOR
Руслан Дамирович, ОГОНЬ!
а теперь как это сделать с курсором ибо юнитов порядка 10к+ и временных точек тоже некислое количество, причем у каждого юнита...
...
Рейтинг: 0 / 0
09.01.2018, 19:22
    #39581260
peskauskas
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Transact-SQL @CURSOR
iii2,
14,0 нужно сделать салюшн именно в трансакте
...
Рейтинг: 0 / 0
09.01.2018, 20:12
    #39581287
iiyama
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Transact-SQL @CURSOR
peskauskas,

если 14й, то можете еще прикрутить Lead/Lag, а вот зачем Вам курсор до меня не доходит, чтобы дольше обрабатывалось или начальник сказал?
...
Рейтинг: 0 / 0
09.01.2018, 21:19
    #39581310
peskauskas
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Transact-SQL @CURSOR
peskauskas,
Код: 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.
CREATE table test.dbo.test
(
id int,
name Varchar (10),
time time(2),
line int
)

--Создаем переменные
DECLARE @id int =1
DECLARE @MngUnit varchar(10)
DECLARE @IPO int
DECLARE @time int
DECLARE @timePast time (2)

--Создадим курсор
DECLARE cur1 CURSOR FOR 
SELECT top 10 id, MngUnit, IPO FROM test.dbo.Position

--Откроем курсор
OPEN cur1

--Выборка данных первой строки
FETCH NEXT FROM cur1 INTO @id, @MngUnit, @ipo

--Пока есть данные в курсоре - выборка циклом
WHILE @@FETCH_STATUS = 0
BEGIN 
    SELECT @id as ID, @MngUnit as UNIT, @ipo as 'TIME OFF'
        -------ВОТ ТУТ ДОЛЖЕН БЫТЬ ЕЩЕ ОДИН КУРСОР, КОТОРЫЕ ПЕРЕБИРАЕТ КРИТЕРИИ----
	--Выборка следующей строки
    FETCH NEXT FROM cur1 INTO @id, @MngUnit, @ipo
END

--Закрываем курсор
CLOSE cur1
--Уничтожаем курсор
DEALLOCATE cur1

drop table test.dbo.test




Примерный набросок....

Код: sql
1.
2.
3.
4.
5.
6.
7.
----ЕСЛИ ПЕРЕМЕННАЯ UID ЕСТЬ В СПИСКЕ) , И ((есть разница между реальным и прошлым времинем более 15 секунд ) И ( IPO = 1))  ИЛИ (ipo = 0)
IF (( @UID = (SELECT id FROM Unit WHERE u.id = @UID ) AND ( @TR - @TP >= '00:00:15' ) AND ( p.IPO = 1 )) OR ( @UID = u.id ) AND ( p.IPO = 0 ) 
	BEGIN 	---- то! прибавить @TS разницу @TR - @TP) 
		SET @TS = @TS + (p.TimeStamp - @TP)
	END
ELSE ---- ЕСЛИ УСЛОВИЯ НЕ ВЫПОЛНЯЮТСЯ, ТО = @UID + 1 (соотв, сл ряд) 
	SET @UID = @UID + 1
...
Рейтинг: 0 / 0
09.01.2018, 21:24
    #39581314
Гавриленко Сергей Алексеевич
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Transact-SQL @CURSOR
Какой прекрасный говнокод! Давайте еще!
...
Рейтинг: 0 / 0
09.01.2018, 22:18
    #39581339
peskauskas
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Transact-SQL @CURSOR
Гавриленко Сергей Алексеевич,

Если не можете помочь, зачем показывать всем, что вы этого не можете ?
...
Рейтинг: 0 / 0
09.01.2018, 23:38
    #39581367
peskauskas
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Transact-SQL @CURSOR
peskauskas,

Помогите это правильно записать пожалуйста.
...
Рейтинг: 0 / 0
09.01.2018, 23:42
    #39581370
peskauskas
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Transact-SQL @CURSOR
iiyama,

Готов выслушать ваше решение, начальник упомянул про курсор причем 2-го уровня...
у меня в пятницу тестирование и скажем так, мне дали время и пример для того что бы подготовиться.
Я могу все это написать в Экселе, в котором я разбираюсь куда лучше, но задача сделать решение в трансакте и не факт что курсором.
В целом, от меня будут ждать результат, а как я его достигну это мое дело...
...
Рейтинг: 0 / 0
10.01.2018, 00:46
    #39581385
Гавриленко Сергей Алексеевич
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Transact-SQL @CURSOR
peskauskasГавриленко Сергей Алексеевич,

Если не можете помочь, зачем показывать всем, что вы этого не можете ?На "слабо" своих корешей в подъезде будете разводить. Прощайте.
...
Рейтинг: 0 / 0
10.01.2018, 09:29
    #39581482
uaggster
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Transact-SQL @CURSOR
peskauskasРуслан Дамирович, ОГОНЬ!
а теперь как это сделать с курсором ибо юнитов порядка 10к+ и временных точек тоже некислое количество, причем у каждого юнита...
Так оно и для 10к юнитов будет работать, не снижая производительности.
Курсор будет работать примерно в 1000 раз медленнее (это не фигура речи).

"Если ты знаешь синтаксис курсора - это уже повод относиться к тебе с подозрением" (С) Олонский, если мне память не изменяет.
...
Рейтинг: 0 / 0
10.01.2018, 11:05
    #39581567
iiyama
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Transact-SQL @CURSOR
peskauskas,

Ну если начальник сказал, делайте как он сказал, на то он и началнеГ. Но его хотелка делается запросом без всяких курсоров. См. пример Руслан Дамирович

пример Б. Вложенный курсор
...
Рейтинг: 0 / 0
10.01.2018, 11:10
    #39581572
peskauskas
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Transact-SQL @CURSOR
uaggster,

Я его и не знаю, точнее понять не могу до конца.
он мне не впился никуда, но такая задача тестирования.
=(
у кого можно проконсультироваться в месенджере по синтаксису ? 89250437967
...
Рейтинг: 0 / 0
10.01.2018, 12:04
    #39581630
peskauskas
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Transact-SQL @CURSOR
peskauskas,

считает, но не правильно... =(

сократил количество данных и подписал для наглядности

INSERT INTO @data VALUES
( 2224, '2017-05-01T12:10:03', 0 ), -- время 1
( 2224, '2017-05-01T12:10:19', 0 ), -- время 2 отличается на 16 секунд
( 2224, '2017-05-01T12:10:32', 1 ), -- онлайн, отличается от пред идущего на 23 секунды
( 2224, '2017-05-01T12:10:36', 1 ) -- итого должно показать итоговое время оффлай 16+23 = 39 секунд
;
/*Острова. Детская задачка по определению границы изменения значений*/
WITH

считает
ID IPO DURATION
2224 0 43832
...
Рейтинг: 0 / 0
10.01.2018, 12:09
    #39581639
Руслан Дамирович
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Transact-SQL @CURSOR
peskauskaspeskauskas,
считает, но не правильно... =(
сократил количество данных и подписал для наглядности

Дружище, научись читать комментарии; осознай, что именно делает код; модифицируй под свои нужды.
Подсказка: оно считает, что если 0 был первым, то он был на начало дня, он считает, что если последней была 1, то 1 была до конца дня.
...
Рейтинг: 0 / 0
10.01.2018, 12:48
    #39581670
peskauskas
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Transact-SQL @CURSOR
Руслан Дамирович,

Пардон !!! слеп =( бьюсб несколько дней, мозги в кашу =(
...
Рейтинг: 0 / 0
10.01.2018, 13:51
    #39581713
peskauskas
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Transact-SQL @CURSOR
peskauskas,

Кто может мне расжевать курсор ?! плз.
=(
...
Рейтинг: 0 / 0
10.01.2018, 13:55
    #39581717
alexeyvg
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Transact-SQL @CURSOR
peskauskaspeskauskas,

Кто может мне расжевать курсор ?! плз.
=(Так какие вопросы, конкретно?
Вы же показали тут код с курсором, там всё нормально.
...
Рейтинг: 0 / 0
10.01.2018, 15:28
    #39581804
peskauskas
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Transact-SQL @CURSOR
alexeyvg,

Да, но!
в центре есть камент
-------ВОТ ТУТ ДОЛЖЕН БЫТЬ ЕЩЕ ОДИН КУРСОР, КОТОРЫЕ ПЕРЕБИРАЕТ КРИТЕРИИ----
в место которого теоретически должен быть

----ЕСЛИ ПЕРЕМЕННАЯ UID ЕСТЬ В СПИСКЕ) , И ((есть разница между реальным и прошлым времинем более 15 секунд ) И ( IPO = 1)) ИЛИ (ipo = 0)
IF (( @UID = (SELECT id FROM Unit WHERE u.id = @UID ) AND ( @TR - @TP >= '00:00:15' ) AND ( p.IPO = 1 )) OR ( @UID = u.id ) AND ( p.IPO = 0 )
BEGIN ---- то! прибавить @TS разницу @TR - @TP)
SET @TS = @TS + (p.TimeStamp - @TP)
END
ELSE ---- ЕСЛИ УСЛОВИЯ НЕ ВЫПОЛНЯЮТСЯ, ТО = @UID + 1 (соотв, сл ряд)
SET @UID = @UID + 1

но как правильно его записать я пока не понял =(
...
Рейтинг: 0 / 0
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Transact-SQL @CURSOR / 25 сообщений из 36, страница 1 из 2
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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