SQLinfo.ru - Все о MySQL Webew.ru: теория и практика веб-технологий

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

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

Вы не зашли.

#1 31.03.2009 16:48:56

persty
Участник
Зарегистрирован: 31.03.2009
Сообщений: 7

Помогите сделать выборку группы значений

CREATE TABLE test (
  _id int(11) NOT NULL auto_increment,
  _code varchar(16) NOT NULL default '',
  _date int(11) NOT NULL default '0',
  PRIMARY KEY  (_id),
  KEY _code (_code)
) TYPE=MyISAM;

Начиная с некоей даты D (_date>D) надо выбрать одну следующую запись, или X следующих записей, если разность по полю _date между ними не превышает Y.

Извиняюсь, что мудрено, мозги закипают уже.

Неактивен

 

#2 31.03.2009 16:59:14

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6757

Re: Помогите сделать выборку группы значений

Если таблица небольшая, то лучше всего подходит способ "в лоб":

SELECT * FROM test WHERE _date > X ORDER BY _date LIMIT 1
UNION
SELECT * FROM test WHERE _date BETWEEN X AND (X+Y);

Неактивен

 

#3 31.03.2009 17:24:20

persty
Участник
Зарегистрирован: 31.03.2009
Сообщений: 7

Re: Помогите сделать выборку группы значений

В том-то и заковыка, что блок дат может отстоять от D не на величину Y, а на любую. Надо лишь, чтобы искомые даты лежали в пределах Y.
Например, идут в таблице даты
1
5
6
При Y=2 даты 5 и 6 не попадут в выборку.

Неактивен

 

#4 31.03.2009 19:15:45

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6757

Re: Помогите сделать выборку группы значений

Упс, я в предыдущем примере почему-то решил, что дата-параметр - Х. А она - D.
Правильно читать
SELECT * FROM test WHERE _date > D ORDER BY _date LIMIT 1
UNION
SELECT * FROM test WHERE _date BETWEEN D AND (D+Y);

Неактивен

 

#5 31.03.2009 19:40:31

persty
Участник
Зарегистрирован: 31.03.2009
Сообщений: 7

Re: Помогите сделать выборку группы значений

Да, я обратил внимание, но сути дела это не меняет. smile
По второму селекту будут выбраны ближайшие два дня, т.е. ни одной записи.
А в действительности должны быть выбраны 5-е и 6-е.

Отредактированно persty (31.03.2009 19:41:54)

Неактивен

 

#6 31.03.2009 20:30:27

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6757

Re: Помогите сделать выборку группы значений

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

Неактивен

 

#7 31.03.2009 20:36:31

persty
Участник
Зарегистрирован: 31.03.2009
Сообщений: 7

Re: Помогите сделать выборку группы значений

Согласен, я не четко сформулировал условие (между ними можно трактовать как между D и искомыми).
Правильно так
Начиная с некоей даты D (_date>D) надо выбрать одну следующую запись, или X следующих записей, если разность по полю _date между множеством записей X не превышает Y.

Неактивен

 

#8 31.03.2009 20:45:41

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6757

Re: Помогите сделать выборку группы значений

Не понимаю. Пример приведите, пожалуйста smile
Пусть есть строки 1, 6, 7, 17, 18, 37.

Какие-нибудь комбинации D, X, Y и вывода, чтобы было понятно, что Вы хотите smile

Неактивен

 

#9 01.04.2009 07:02:12

LazY
_cмельчак
MySQL Authorized Developer and DBA
Зарегистрирован: 02.04.2007
Сообщений: 849

Re: Помогите сделать выборку группы значений

Я, кажется, понял, что нужно: в любом случае выбирается запись с _date > D. Затем выбирается следующая - вторая - если между ней и первой разница меньше Y, затем - третья, если между третьей и второй разница меньше Y и т.д..

Долго раздумывал над этой задачей. На мой взгляд, есть единственный способ; несколько извращенно выглядит, но зато работает, вроде, правильно (и даже ключи использовать должен, если понадобится):

SELECT * FROM test WHERE _date > 1 AND @x := _date LIMIT 1
UNION
SELECT * FROM test WHERE _date > @x AND _date < @x + 4 AND @x := _date


Вещи типа WHERE @x := _date нужны, чтобы за один запрос успеть присвоить нужное значение переменной @x.

Обратите внимание, что в WHERE второго запроса выражение @x := _date должно стоять обязательно последним, после сравнения значения столбца _date с @x, иначе сравнение будет проходить с неправильным значением перемнной, и результат будет не тем, что надо.

P.S. Хорошо, что у Вас в любом случае выбирается хотя бы одна запись - а то бы не получилось.

Неактивен

 

#10 01.04.2009 16:16:25

persty
Участник
Зарегистрирован: 31.03.2009
Сообщений: 7

Re: Помогите сделать выборку группы значений

Верно, но несколько проще. Если совсем точно:
Затем выбирается следующая - вторая - если между ней и первой разница меньше Y, затем - третья, если между третьей и первой разница меньше Y и т.д..

И надо еще учесть, что могут быть одинаковые даты. Например, при последовательности 2,2,3,8,10 и Y=4 по запросу выше будут выбраны только 2,3, тогда как надо 2,2,3.

Да и сам запрос... пока никак у меня не пашет, выбирает только первую запись с _date > D...

Отредактированно persty (01.04.2009 16:18:40)

Неактивен

 

#11 01.04.2009 16:48:25

Magz
Гуру
Откуда: Москва
Зарегистрирован: 18.09.2007
Сообщений: 112

Re: Помогите сделать выборку группы значений

Коллеги, может я не врубился в задачу, но почему не получается так:

Код:

SELECT test.* FROM
test JOIN (SELECT _date FROM test t2 WHERE t2._date > D LIMIT 0, 1) t3 ON (test._date >= t3._date)
WHERE test._date <= DATE_SUB(t3._date, INTERVAL +Y DAY)
LIMIT 0, X

Неактивен

 

#12 02.04.2009 11:48:15

persty
Участник
Зарегистрирован: 31.03.2009
Сообщений: 7

Re: Помогите сделать выборку группы значений

"Буратино был тупой..." (С) smile
Не могу осилить логику последнего запроса мне, видимо, не дано. Мудрено как-то. sad
Придется вытягивать все даты диапазона отдельным запросом, затем обрабатывать PHP, затем вторым запросом вытягивать уже записи с установленнымим датами.
Всем большое спасибо, в процессе задавания вопросов задача стала яснее.

Неактивен

 

#13 02.04.2009 12:55:00

Magz
Гуру
Откуда: Москва
Зарегистрирован: 18.09.2007
Сообщений: 112

Re: Помогите сделать выборку группы значений

Persty, а сам запрос-то работает или Вы не пробовали?
Логика проста: сначала вытаскиваем первую запись, которая больше даты D (

(SELECT _date FROM test t2 WHERE t2._date > D LIMIT 0, 1) t3
). Объединив это множество с исходной таблицей по условию "дата в исходной таблице больше или равно найденной дате" мы получим множество всех записей у которых дата больше D и ту самую первую дату, которая больше D и с которой нужно будет сравнивать остальные даты. А потом выбираем из полученного множества все даты, разница между которыми и найденой "первой датой больше D" будет меньше Y. И в конце ограничиваем выборку по X.

Неактивен

 

#14 02.04.2009 16:56:53

persty
Участник
Зарегистрирован: 31.03.2009
Сообщений: 7

Re: Помогите сделать выборку группы значений

Урра, заработало! Тепрь я все понял, логика ясна. Не работало, потому что я в одном месте пропустил FROM_UNIXTIME для даты. Спасибо!

Неактивен

 

Board footer

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