2013-07-28 2 views
0

Просто не получается понять это, хотя это кажется довольно простым.тип соединения для сравнения двух строк

Table: Attd (...short for Attendance) 
Visit Person Status Date 
1  1  Member 2011-01-31 
2  1  Member 2011-02-05 
3  2  Member 2011-02-05 
4  3  Not  2011-01-07 
5  1  Not  2011-01-25 
6  1  Not  2011-01-20 
7  1  Not  2011-02-03 

Данные относятся к посещению населенных пунктов физическими лицами, в том числе если у них есть членство (столбец состояния).

Как бы вы выбрали посещения, которые произошли за неделю до того, как кто-то стал участником (Тот же человек: Статус = Не -> Статус = Член)? [Выходной ряд 5 выше.]

Например, Лицо 2 стало участником без посещения ранее, поскольку у них не было статуса = Нет, пока они не присоединились.

Лицо 3 посетило как нечлен и никогда не возвращалось.

И, человек 1 посетили как не являющегося членом (Status = Not on 2011-01-25) и стали членом в течение одной недели (Статус = Участник 2011-01-31).

Предварительные работы:
a. Довольно уверен, что ответ содержит самостоятельное присоединение
b. Функция dateAdd помогает удовлетворить за одну неделю до состояния

ответ

1

Попробуйте этот простой запрос:

SELECT t1.Person 
FROM 
    (SELECT * 
    FROM attd 
    WHERE status = 'member')T1 
INNER JOIN 
    (SELECT * 
    FROM attd 
    WHERE status = 'not')T2 ON T1.Person = T2.Person 
WHERE datediff(dd,T2.Date,T1.Date)<=7 

Вы можете найти рабочий пример на SQLFiddle.

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

0

Агрегация первого использования для расчета даты членства для каждого человека. Это, предположительно, минимальная дата, когда есть статус 'Member'. Тогда же объединение обратно к столу, чтобы получить более ранние визиты:

select * 
from (select a.person, min(date) as MemberDate 
     from Attendance a 
     where status = 'Member' 
     group by a.person 
    ) m join 
    Attendance aprev 
    on m.person = aprev.person and 
     datediff(d, aprev.date, MemberDate) <= 7 and 
     aprev.status = 'Not'; 

Строго говоря, последнее условие 'aprev.status = 'Not' является необходимым, так как только эти статусы до даты членов. Однако, я думаю, это уточняет намерение запроса.

Смежные вопросы