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