sql为每个成员选择最近的日期时间

时间:2013-06-06 18:22:07

标签: sql sql-server ssms

我的大脑今天拒绝与我合作,实际上正确地思考这个问题所以我希望得到一些反馈:我想从每个成员返回他们最近进入系统的一条记录,但到目前为止我显然有只能为任何成员的最近日期时间返回单个记录。我知道这个问题不是很正确但我的大脑拒绝真正合作......

SQL:

SELECT 
    cm.FNAME, 
    cm.LNAME, 
    cl.entry_access_point, 
    cl.date_entered, 
    cl.res_id, 
    dbo.HourMinuteSecond(cl.date_entered, getUTCDate())[Day:Hour:Minute:Second]
FROM 
    cred.members cm, cred.allocate_log cl
WHERE 
    cm.member_id = cl.member_id AND
    cl.date_exited IS NULL AND 
    cl.evt_id = @eventId AND
    date_entered IN (SELECT max(cl.date_entered)
                     FROM cred.allocate_log cl, cred.members cm
                     WHERE cl.member_id = cm.member_id)
ORDER BY 
    cl.date_entered;

3 个答案:

答案 0 :(得分:2)

执行此类查询的最佳方法是使用row_number()。此外,您应该学习使用join语法,而不是将连接放在where子句中。

select t.*
from (SELECT cm.FNAME, cm.LNAME, cl.entry_access_point, cl.date_entered, cl.res_id, 
             dbo.HourMinuteSecond(cl.date_entered, getUTCDate()) as [Day:Hour:Minute:Second],
             ROW_NUMBER() over (partition by cm.member_id order by cl.date_enetered desc) as seqnum
      FROM cred.members cm join
           cred.allocate_log cl
           on cm.member_id = cl.member_id
      WHERE cl.date_exited IS NULL AND 
            cl.evt_id = @eventId
     ) t
ORDER BY date_entered;

答案 1 :(得分:1)

select 
   those fields
from cred.members cm,
join (
select member_id, max(date_entered) maxdate
from cred.allocate_log
where date_exited is null
and evt_id = @eventId
group by member_id
) s on cm.member_id = s.member_id
join cred.allocate_log cl on
  cm.member_id = cl.member_id
  and cl.date_entered = s.maxdate

你也可以使用非标准CROSS APPLY运算符,如果可能存在多个具有给定date_entered的行,则可以使事情变得更简单

select
   those fields
from cred.members cm
cross apply (
    select top 1
       fields from log
    from cred.allocate_log cl
    where cm.member_id = cl.member_id
    and date_exited is null
    and evt_id = @eventId
    order by date_entered desc
)

答案 2 :(得分:1)

只需在子查询中添加member_id规则:

SELECT 
cm.FNAME, 
cm.LNAME, 
cl.entry_access_point, 
cl.date_entered, 
cl.res_id, 
dbo.HourMinuteSecond(cl.date_entered, getUTCDate())[Day:Hour:Minute:Second]
FROM cred.members cm, cred.allocate_log cl
WHERE cm.member_id = cl.member_id AND
    cl.date_exited IS NULL AND 
    cl.evt_id = @eventId AND
    date_entered IN (
        SELECT max(cl.date_entered)
        FROM cred.allocate_log cl, cred.members cms
        WHERE cl.member_id = cms.member_id and cms.member_id = cm.member_id)
ORDER BY cl.date_entered

但是你也需要在子查询中使用evt_id语句,它可以像这样简化:

SELECT 
    cm.FNAME, 
    cm.LNAME, 
    cl.entry_access_point, 
    cl.date_entered, 
    cl.res_id, 
    dbo.HourMinuteSecond(cl.date_entered, getUTCDate())[Day:Hour:Minute:Second]
    FROM cred.members cm, cred.allocate_log cl
    WHERE cm.member_id = cl.member_id AND
        cl.date_exited IS NULL AND 
        cl.evt_id = @eventId AND
        date_entered >= ALL (
            SELECT cl.date_entered
            FROM cred.allocate_log cls
            WHERE cls.member_id = cm.member_id AND cls.evt_id = cl.evt_id)
    ORDER BY cl.date_entered

更改子查询中表的别名:

SELECT 
        cm.FNAME, 
        cm.LNAME, 
        cl.entry_access_point, 
        cl.date_entered, 
        cl.res_id, 
        dbo.HourMinuteSecond(cl.date_entered, getUTCDate())[Day:Hour:Minute:Second]
        FROM cred.members cm, cred.allocate_log cl
        WHERE cm.member_id = cl.member_id AND
            cl.date_exited IS NULL AND 
            cl.evt_id = @eventId AND
            date_entered >= ALL (
                SELECT cls.date_entered
                FROM cred.allocate_log cls
                WHERE cls.member_id = cm.member_id AND cls.evt_id = cl.evt_id)
        ORDER BY cl.date_entered