Доброго времени суток. Второй день бьюсь - но, видимо, подотупел) Есть табличка с 3мя полями period- дата изменения person - человек live_state - флаг-состояние. Проживает/не проживает Так вот. Нужно одним запросом выбрать за период изменение состава людей, состояние которых не изменялось более 3х месяцев. С программной обработкой запроса просто. Но загорелся сделать запросом и уже сомневаюсь, возможно ли это вообще
Можно наверное выбрать тех, у кого состояние хоть раз было одно, потом выбрать тех у кого хоть раз остояние было другое и сджоинить. вроде как в таких случаях помогает задать одной и той же таблице разные AS.
В общем случае, у каждого человека может быть неограниченное число таких таких состояний. Важнее выбрать те за период, у которых нет противоположного впределах 3х месяцев
на самом деле все проще. группируем по person, и считаем кол-во live_state за период. нам нужны те, у кого за период live_state не менялся, т.е. кол-во==1 чтото типа: Код (Text): SELECT person, COUNT(live_state) cnt FROM TableName WHERE PERIOD >= '01.01.2012' AND PERIOD<='01.04.2012' GROUP BY PERSON HAVING cnt=1 правда тут остается один вопрос. если live_state менялся ДО периода, а в периоде вообще не менялся. получается что он , по логике, должен попасть в результат(так как live_state не менялся), но мой запрос его не выведет, так как в период просто не попадает по дате
Мой косяк. Наверное, неверно описал задачу. Сделаем задачу совсем простой и получим движение всех людей за период без каких либо дополнительных условий. Запрос будет выглядеть следующим образом: Код (Text): SELECT * FROM TableName WHERE PERIOD >= '01.01.2012' AND PERIOD<='08.04.2012' И все казалось бы чудесно и замечательно... Но... сюда попали и люди, которые находились или будут находиться на месте менее 3х месяцев. Т.е. по результатам выборки, надо, посмотрев реальную дату движения человека, и посмотреть (от этой даты) вперед и назад по 3 месяца. Если движения не было - человек нам подходит Вот, как-то так =)
тоесть чтото типа такого? Код (PHP): SELECT t.person ,t.period ,t.live_state ,(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 ,(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 FROM TableName t WHERE PERIOD>='01.01.2012' AND PERIOD<='08.04.2012' это конечно тупое решение в лоб. просто проверить правильно ли я понял логику того что вам нужно?
Попробуйте так: Код (Text): select * from (Ваш запрос) t inner join TableName tt on tt.Person = t.person and 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)) п.с. Работоспособность не гарантирую - не проверял. (набивать тест-данные лень)