用于比较两行的连接类型

时间:2013-07-28 13:04:52

标签: sql-server

似乎无法弄清楚这一点,虽然看起来很简单。

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个人之前没有访问成为会员,因为他们在加入之前没有Status = Not。

第3个人作为非会员访问,但从未回来过。

并且,第1人作为非会员访问(Status = Not on 2011-01-25)并在一周内成为会员(Status = 2011-01-31成员)。

初步工作:
一个。很确定答案包含自我加入
湾dateAdd函数帮助满足条件前一周

2 个答案:

答案 0 :(得分: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找到一个有效的例子。

希望这对您有所帮助,如果您有任何其他问题,请随时与我联系。

答案 1 :(得分: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'是不必要的,因为这些是成员日期之前的唯一状态。但是,我认为它澄清了查询的意图。