powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Разбить одну запись на несколько
8 сообщений из 8, страница 1 из 1
Разбить одну запись на несколько
    #38904513
Pim.
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Всем доброго времени суток!

Изначально имеется следующая таблица (события триггеров), отсортированная по triggerid и time:
triggerid eventid time value46394 18225570 04.03.2015 10:52 046394 18225522 04.03.2015 10:51 146394 18037642 20.02.2015 12:27 046394 18021630 20.02.2015 07:41 146394 17965712 17.02.2015 12:46 046395 18033138 20.02.2015 11:23 046395 18025510 20.02.2015 11:11 146395 17956724 16.02.2015 17:10 046395 17956652 16.02.2015 17:09 146395 17928093 13.02.2015 20:30 0

Написал запрос, который к каждому событию конкретного триггера добавляет время следующего события для данного триггера
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
SET @next_date=NULL, @id=0;
SELECT
t.triggerid,
t.eventid,
t.time,
t.`value`,
if(@id=t.triggerid, @next_date, (NULL) AND (@id:=t.triggerid)) `nexttime`,
@next_date:=t.time
FROM
(
<...> --Формируется таблица описанная выше
) as t



Получается следующая таблица:
triggerid eventid time value nexttime @next_date:=t.time46394 18225570 04.03.2015 10:52 0 04.03.2015 10:5246394 18225522 04.03.2015 10:51 1 04.03.2015 10:52 04.03.2015 10:5146394 18037642 20.02.2015 12:27 0 04.03.2015 10:51 20.02.2015 12:2746394 18021630 20.02.2015 07:41 1 20.02.2015 12:27 20.02.2015 07:4146394 17965712 17.02.2015 12:46 0 20.02.2015 07:41 17.02.2015 12:4646395 18033138 20.02.2015 11:23 0 20.02.2015 11:2346395 18025510 20.02.2015 11:11 1 20.02.2015 11:23 20.02.2015 11:1146395 17956724 16.02.2015 17:10 0 20.02.2015 11:11 16.02.2015 17:1046395 17956652 16.02.2015 17:09 1 16.02.2015 17:10 16.02.2015 17:0946395 17928093 13.02.2015 20:30 0 16.02.2015 17:09 13.02.2015 20:30

Возникло несколько вопросов:
1) Как убрать вывод столбца @next_date:=t.time?
2) Как сделать, чтобы при максимальной дате вместо null выводилось текущее время. Когда прописываю NOW() или CURRENT_TIMESTAMP выводит почему-то "1"
3) Столбец nexttime почему-то получается в формате BLOB, поэтому при выводе Navicat пишет (BLOB) вместо значения. При экспорте все нормально. Объясните пожалуйста, почему так происходит и как это исправить?

Также есть одна задача:
Нужно для каждого eventid, при условии, что nexttime и time разные дни (TO_DAYS(nexttime)>TO_DAYS(time)), разбить запись на кол-во дней. Например, из такой записи
triggerid eventid time value nexttime46394 17965712 17.02.2015 12:46 0 20.02.2015 07:41
мне нужно получить 4 записи:
triggerid eventid time value nexttime46394 17965712 17.02.2015 12:46 0 17.02.2015 23:5946394 17965712 18.02.2015 00:00 0 18.02.2015 23:5946394 17965712 19.02.2015 00:00 0 19.02.2015 23:5946394 17965712 20.02.2015 00:00 0 20.02.2015 07:41
...
Рейтинг: 0 / 0
Разбить одну запись на несколько
    #38905074
Pim.
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Очень прошу помощи! Вопрос актуален.
...
Рейтинг: 0 / 0
Разбить одну запись на несколько
    #38905099
anvano
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Как-то так. Хз правда, сколько у вас данных в таблице и будет ли быстро два раза перенумеровывать строки :)

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
SELECT v.triggerid,v.eventid,v.time, v.value, ifnull(v1.time,now()) nexttime 
FROM (
   SELECT t.*, @rownum := @rownum + 1 AS rank FROM test_tab t, (SELECT @rownum := 0) r
   ORDER BY triggerid , time
 ) v
LEFT JOIN
( 
   SELECT t.*, @rownum := @rownum + 1 AS rank FROM test_tab t, (SELECT @rownum := 0) r
   ORDER BY triggerid , time
 ) v1 ON (v1.triggerid = v.triggerid AND v1.rank = v.rank+1)  
...
Рейтинг: 0 / 0
Разбить одну запись на несколько
    #38905102
Pim.
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
anvano,

от JOIN изначально отказался в пользу пользовательских переменных как раз потому что строк более 600к. А в будущем будет еще в разы больше.

Есть ли идеи, как это можно реализовать через ПП?
...
Рейтинг: 0 / 0
Разбить одну запись на несколько
    #38905301
Pim.
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
anvano,

и не могли бы пояснить, на какой из озвученных вопросов Вы ответили?
...
Рейтинг: 0 / 0
Разбить одну запись на несколько
    #38905356
Pim.
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ответы на вопросы нашел.

Задача более, чем актуальна!
...
Рейтинг: 0 / 0
Разбить одну запись на несколько
    #38905427
anvano
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
автор1) Как убрать вывод столбца @next_date:=t.time?


Сделать обрамляющий селект, в котором выводить только нужные столбцы

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
SELECT triggerid, eventid, time, value, IFNULL(nexttime,NOW()) nexttime 
FROM (
  SELECT
  t.triggerid,
  t.eventid,
  t.time,
  t.`value`,
  if(@id=t.triggerid, @next_date, (NULL) AND (@id:=t.triggerid)) `nexttime`,
  @next_date:=t.time
  FROM
  (
  <...> --Формируется таблица описанная выше
  ) as t
) v;




автор2) Как сделать, чтобы при максимальной дате вместо null выводилось текущее время. Когда прописываю NOW() или CURRENT_TIMESTAMP выводит почему-то "1"


У вас из-за преобразования типов выводится результат битового оператора NOW() AND (@id:=t.triggerid) - он TRUE значит 1.
А когда вы делаете AND с NULL - то результат будет NULL.

Вместо NULL можно выводить NOW() в том же обрамляющем селекте из первого пункта, конструкцией IFNULL() (см. выше)

автор3) Столбец nexttime почему-то получается в формате BLOB, поэтому при выводе Navicat пишет (BLOB) вместо значения. При экспорте все нормально. Объясните пожалуйста, почему так происходит и как это исправить?


Он не BLOB а строка. Все пользовательские переменные при использовании в селекте трактуются как строки, даже если вы проводите с ними арифметические операции. Этот момент вроде явно описан в документации по пользовательским переменным.
Чтобы сделать дату - скастуйте явно в нужный тип

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
SELECT triggerid, eventid, time, value, IFNULL(nexttime,NOW()) nexttime 
FROM (
SELECT
t.triggerid,
t.eventid,
t.time,
t.`value`,
cast(if(@id=t.triggerid, @next_date, (NULL) AND (@id:=t.triggerid)) as datetime) `nexttime`,
@next_date:=t.time
  FROM
  (
  <...> --Формируется таблица описанная выше
  ) as t
) v;



Плюс еще непонятно, что за магия у вас скрывается за словами "<...> --Формируется таблица описанная выше" какие там типы данных у столбцов. Если там вместо дат - строки (или BLOB-ы) то какбы что же вы тогда хотели получить.
...
Рейтинг: 0 / 0
Разбить одну запись на несколько
    #38905429
Pim.
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
anvano,

Да, спасибо. Ранее 1 и 2 пункты решил именно так. 3 решил просто: вместо SET @next_date=NULL - SET @next_date=''

Задачу также уже решил. Работает как нужно.

Если кому интересно:
Код: 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.
DROP TEMPORARY TABLE IF EXISTS temp, days;
SET @next_date='', @id=0;

CREATE TEMPORARY TABLE temp
SELECT 
m.triggerid,
m.eventid,
m.curtime,
m.`value`,
IFNULL(m.nexttime,now()) nexttime,
IFNULL(TO_DAYS(nexttime)-TO_DAYS(curtime),TO_DAYS(now())-TO_DAYS(curtime)) as daydiff
FROM
(
SELECT
t.*,
if(@id=t.triggerid, @next_date, (null) AND (@id:=t.triggerid)) `nexttime`,
@next_date:=t.curtime
FROM
(
<...> --Формируется таблица описанная выше
) as t
)m;

CREATE TEMPORARY TABLE days
SELECT  @curRow := @curRow + 1 AS daycnt
FROM    `events`
JOIN    (SELECT @curRow := -1) r
WHERE   @curRow<(SELECT MAX(daydiff) FROM temp);

SELECT
triggerid,
eventid,
`value`,
CASE
WHEN daycnt=0 THEN curtime
ELSE DATE_ADD(TIMESTAMP(DATE(curtime)),INTERVAL daycnt DAY)
END curtime,
CASE
WHEN daydiff <> daycnt THEN TIMESTAMP(DATE_ADD(DATE_ADD(DATE(nexttime),INTERVAL (-daydiff+daycnt+1) DAY),INTERVAL -1 SECOND))
ELSE nexttime
END nexttime
FROM temp, days
WHERE 
daydiff>=daycnt
...
Рейтинг: 0 / 0
8 сообщений из 8, страница 1 из 1
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Разбить одну запись на несколько
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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