SQLinfo.ru - Все о MySQL

Форум пользователей MySQL

Задавайте вопросы, мы ответим

Вы не зашли.

#1 29.11.2012 21:07:20

demiurg
Завсегдатай
Зарегистрирован: 08.05.2011
Сообщений: 46

Как бы сделать такой запрос...

Здравствуйте. Помогите пожалуйста сделать так запрос:

Есть таблица:
device_id |DT|Snum|par
1       |2011-08-10 14:12:00       |      1    |    fggdfg
1       |2011-08-10 14:12:00       |      2    |    fggdfg
1       |2011-08-10 14:13:00       |      2    |    fggdfg
1       |2011-08-10 14:12:00       |      3    |    fggdfg
1       |2011-08-10 14:12:00       |      1    |    fggdfg

Надо вывести только те значения Snum которые существуют( по полю DT) в пределах NOW()-INTERVAL 1 MONTH, но НЕ СУЩЕСТВУЮТ в пределах (NOW() -INTERVAL 24 HOURS.
Т.е. если по русски в приближении к реальности, надо отловить те серийные номера Snum устройств, которые не выдали информацию за последние сутки, но выдавали её в течении последнего месяца. Чото не варит голово как это сделать smile

Отредактированно demiurg (29.11.2012 21:36:54)

Неактивен

 

#2 30.11.2012 00:16:19

vasya
Архат
MySQL Authorized Developer
Откуда: Орел
Зарегистрирован: 07.03.2007
Сообщений: 5842

Re: Как бы сделать такой запрос...

select Snum from `таблица` where DT > (NOW()-INTERVAL 1 MONT) and DT < (NOW() -INTERVAL 24 HOURS);

Неактивен

 

#3 30.11.2012 03:59:22

demiurg
Завсегдатай
Зарегистрирован: 08.05.2011
Сообщений: 46

Re: Как бы сделать такой запрос...

Но этот запрос простро выведет значения в диапазоне NOW - месяц до NOW - день.
--
А надо вывести только те, которые не попадают в диапазон NOW - день, но есть в диапазоне NOW-месяц.
Я так понимают надо вывести то, что не попадает в пересечение выводов запросов:
select Snum from `таблица` where DT > (NOW()-INTERVAL 1 MONT);
select Snum from `таблица` where DT < (NOW() -INTERVAL 24 HOURS);

Но как ?

Неактивен

 

#4 30.11.2012 04:19:49

vasya
Архат
MySQL Authorized Developer
Откуда: Орел
Зарегистрирован: 07.03.2007
Сообщений: 5842

Re: Как бы сделать такой запрос...

select Snum from
(select Snum from `таблица` where DT > (NOW()-INTERVAL 1 MONT) and DT < (NOW() -INTERVAL 24 HOURS)) t1
left join
(select Snum from `таблица` where DT > (NOW() -INTERVAL 24 HOURS)) t2 using(Snum) where t2.Snum is null
;

Неактивен

 

#5 30.11.2012 13:10:09

demiurg
Завсегдатай
Зарегистрирован: 08.05.2011
Сообщений: 46

Re: Как бы сделать такой запрос...

Спасибо,  заработало!!!
Переработал под себя.

SELECT
Snum,
device_id,
type,
device.LastConnection
from
(select Snum,device_id,type from `information` where DT > (NOW()-INTERVAL 7 DAY) and DT < (NOW() -INTERVAL 25 HOUR)) t1
left join (select Snum,device_id,type from `information` where DT > (NOW() -INTERVAL 25 HOUR)) t2 using(Snum,device_id,type)
left join device ON device.id=device_id
where t2.Snum is null AND device.LastConnection>=(NOW()-INTERVAL 1 DAY) GROUP BY Snum;

Правда вот чо smile
Запрос выполняется аж 0.12с( без таблицы device 0.1c), а запросы:
select Snum,device_id,type from `information` where DT > (NOW()-INTERVAL 7 DAY) and DT < (NOW() -INTERVAL 25 HOUR)
select Snum,device_id,type from `information` where DT > (NOW() -INTERVAL 25 HOUR)
По 0.0004c каждый. А куда уходит всё остальное время? smile Никак нельзя оптимизировать введением индексации?

--
А как бы вывести последнее вхождение Snum в DT?
Т.е. в 2012-11-28 09:11:48 Snum=1234 есть, а в 2012-11-30 10:11:48 - уже отсутствует.Вывести 2012-11-30 09:11:48. Но это же надо одновременно и группировать по Snum и выравнивать по DT - иначе неоднозначность по полю DT выводит.

Отредактированно demiurg (30.11.2012 13:11:14)

Неактивен

 

#6 30.11.2012 13:32:54

vasya
Архат
MySQL Authorized Developer
Откуда: Орел
Зарегистрирован: 07.03.2007
Сообщений: 5842

Re: Как бы сделать такой запрос...

demiurg написал:

А как бы вывести последнее вхождение Snum в DT?
Т.е. в 2012-11-28 09:11:48 Snum=1234 есть, а в 2012-11-30 10:11:48 - уже отсутствует.Вывести 2012-11-30 09:11:48. Но это же надо одновременно и группировать по Snum и выравнивать по DT - иначе неоднозначность по полю DT выводит.

FAQ №16

demiurg написал:

Правда вот чо smile
Запрос выполняется аж 0.12с( без таблицы device 0.1c), а запросы:
select Snum,device_id,type from `information` where DT > (NOW()-INTERVAL 7 DAY) and DT < (NOW() -INTERVAL 25 HOUR)
select Snum,device_id,type from `information` where DT > (NOW() -INTERVAL 25 HOUR)
По 0.0004c каждый. А куда уходит всё остальное время? smile Никак нельзя оптимизировать введением индексации?

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

Неактивен

 

#7 30.11.2012 18:55:13

demiurg
Завсегдатай
Зарегистрирован: 08.05.2011
Сообщений: 46

Re: Как бы сделать такой запрос...

vasya написал:

FAQ №16

спасибо за ссылку! Сделал так:
SELECT `device_id`, SUBSTR(MAX(CONCAT(`DT`, `Snum`)), 1, 19) as `DT`, SUBSTR(MAX(CONCAT(`DT`, `Snum`)), 20) as `Snum` FROM `information` WHERE DT>(NOW() - INTERVAL 1 MONTH) AND DT<(NOW()-INTERVAL 1 DAY) GROUP BY `Snum` ;

SELECT `device_id`, SUBSTR(MAX(CONCAT(`DT`, `Snum`)), 1, 19) as `DT`, SUBSTR(MAX(CONCAT(`DT`, `Snum`)), 20) as `Snum` FROM `information` WHERE  DT>(NOW()-INTERVAL 1 DAY) GROUP BY `Snum` ;

Результаты обоих запросов в php  - array_diff, результат которого и есть нужные строки.
Не знаю -лучше так или нет...Каждый запрос по 0.02с + обработка php.

Неактивен

 

Board footer

Работает на PunBB
© Copyright 2002–2008 Rickard Andersson