За последние 24 часа нас посетили 17078 программистов и 1835 роботов. Сейчас ищут 1675 программистов ...

Запрос - загадка

Тема в разделе "MySQL", создана пользователем ShamahN, 28 окт 2012.

  1. ShamahN

    ShamahN Активный пользователь

    С нами с:
    10 апр 2007
    Сообщения:
    1.449
    Симпатии:
    0
    Адрес:
    г.Волгодонск Роствской обл.
    Доброго времени суток. Второй день бьюсь - но, видимо, подотупел)
    Есть табличка с 3мя полями
    period- дата изменения
    person - человек
    live_state - флаг-состояние. Проживает/не проживает

    Так вот. Нужно одним запросом выбрать за период изменение состава людей, состояние которых не изменялось более 3х месяцев.
    С программной обработкой запроса просто. Но загорелся сделать запросом и уже сомневаюсь, возможно ли это вообще
     
  2. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    Можно наверное выбрать тех, у кого состояние хоть раз было одно, потом выбрать тех у кого хоть раз остояние было другое и сджоинить. вроде как в таких случаях помогает задать одной и той же таблице разные AS.
     
  3. ShamahN

    ShamahN Активный пользователь

    С нами с:
    10 апр 2007
    Сообщения:
    1.449
    Симпатии:
    0
    Адрес:
    г.Волгодонск Роствской обл.
    В общем случае, у каждого человека может быть неограниченное число таких таких состояний. Важнее выбрать те за период, у которых нет противоположного впределах 3х месяцев
     
  4. runcore

    runcore Старожил

    С нами с:
    12 окт 2012
    Сообщения:
    3.625
    Симпатии:
    158
    на самом деле все проще.
    группируем по person, и считаем кол-во live_state за период.
    нам нужны те, у кого за период live_state не менялся, т.е. кол-во==1
    чтото типа:
    Код (Text):
    1.  
    2. SELECT person, COUNT(live_state) cnt
    3. FROM TableName
    4. WHERE PERIOD >= '01.01.2012' AND PERIOD<='01.04.2012'
    5. GROUP BY PERSON
    6. HAVING cnt=1
    правда тут остается один вопрос.
    если live_state менялся ДО периода, а в периоде вообще не менялся.
    получается что он , по логике, должен попасть в результат(так как live_state не менялся), но мой запрос его не выведет, так как в период просто не попадает по дате
     
  5. ShamahN

    ShamahN Активный пользователь

    С нами с:
    10 апр 2007
    Сообщения:
    1.449
    Симпатии:
    0
    Адрес:
    г.Волгодонск Роствской обл.
    Мой косяк. Наверное, неверно описал задачу.
    Сделаем задачу совсем простой и получим движение всех людей за период без каких либо дополнительных условий. Запрос будет выглядеть следующим образом:
    Код (Text):
    1. SELECT *
    2. FROM TableName
    3. WHERE PERIOD >= '01.01.2012' AND PERIOD<='08.04.2012'
    И все казалось бы чудесно и замечательно... Но... сюда попали и люди, которые находились или будут находиться на месте менее 3х месяцев.
    Т.е. по результатам выборки, надо, посмотрев реальную дату движения человека, и посмотреть (от этой даты) вперед и назад по 3 месяца. Если движения не было - человек нам подходит

    Вот, как-то так =)
     
  6. runcore

    runcore Старожил

    С нами с:
    12 окт 2012
    Сообщения:
    3.625
    Симпатии:
    158
    тоесть чтото типа такого?
    Код (PHP):
    1. SELECT 
    2.     t.person
    3.     ,t.period
    4.     ,t.live_state
    5.     ,(SELECT count(tl.period) FROM TableName TL WHERE TL.live_state!=t.live_state AND TL.period>=t.period-3MONTH AND TL.period<t.period) l
    6.     ,(SELECT count(tr.period) FROM TableName TR WHERE Tr.live_state!=t.live_state AND Tr.period>t.period AND Tr.period<t.period+3MONTH) r
    7. FROM TableName t
    8. WHERE PERIOD>='01.01.2012' AND PERIOD<='08.04.2012' 
    это конечно тупое решение в лоб. просто проверить правильно ли я понял логику того что вам нужно?
     
  7. Chushkin

    Chushkin Активный пользователь

    С нами с:
    17 дек 2010
    Сообщения:
    1.062
    Симпатии:
    91
    Адрес:
    Мещёра, Центр, Болото N3
    Попробуйте так:
    Код (Text):
    1. select * from (Ваш запрос) t
    2. inner join TableName tt on tt.Person = t.person and
    3.   not ((tt.Period >= t.period - interval 3 month and tt.Period < t.period) and (tt.Period > t.period and tt.Period <= t.period + interval 3 month))
    п.с. Работоспособность не гарантирую - не проверял. (набивать тест-данные лень)
     
  8. ShamahN

    ShamahN Активный пользователь

    С нами с:
    10 апр 2007
    Сообщения:
    1.449
    Симпатии:
    0
    Адрес:
    г.Волгодонск Роствской обл.
    Спасибо за отклик. Обязательно попробую после работы, - отпишусь