SQL使用GROUP BY查找最近的行
SQL新手听到我在努力解决这个问题!我有一个类似的问题 我有以下数据,所有字段都被定义为字符-没有日期或时间,很遗憾,这要感谢原始DBA糟糕的设计SQL使用GROUP BY查找最近的行,sql,Sql,SQL新手听到我在努力解决这个问题!我有一个类似的问题 我有以下数据,所有字段都被定义为字符-没有日期或时间,很遗憾,这要感谢原始DBA糟糕的设计 Surname Name LoginDate LoginTime Smith John 2014-06-25 13.00 Smith John 2014-06-24 14.00 Smith Susan 2014-06-26 09.00 Smith Susan
Surname Name LoginDate LoginTime
Smith John 2014-06-25 13.00
Smith John 2014-06-24 14.00
Smith Susan 2014-06-26 09.00
Smith Susan 2014-06-26 11.30
Jones Bill 2014-06-25 09.30
Jones Bill 2014-06-25 12.30
Jones Bill 2014-06-26 07.00
我试图从我的输出中得到的是每个人最近的登录,所以我希望看到
Smith John 2014-06-25 13.00
Smith Susan 2014-06-26 11.30
Jones Bill 2014-06-26 07.00
我尝试过临时表的不同组合,在日期和时间上使用CONCAT和MAX函数,但我一直在画空白。我想我知道我需要使用的工具和命令,但我似乎无法将它们正确地串在一起
我知道我必须按名称/姓氏对它们进行分组,然后以某种方式组合日期和时间,以便使用MAX函数,但当我输出它们时,我似乎永远无法使LoginDate和LoginTime在输出上显示为单独的字段,因为它们不包括在我使用的任何组中
有人能告诉我怎么做吗,因为我一开始没有很多头发:你不能使用分组方式。以下是使用“不存在”的方法:
这会将查询转换为:获取表中没有同名行的所有行并稍后登录。如果登录信息存储为单个日期时间,则会更简单
此外,上述内容将适用于几乎所有的SQL数据库。许多数据库支持窗口函数,这些函数也可用于解决此问题。除了Gordon Linoff的答案之外,如果SQL数据库支持窗口函数,您还可以使用它来获得所需的结果:
;With Cte As
(
Select *,
Row_Number() Over (Partition By Surname, Name Order By LoginDate Desc, LoginTime Desc) RN
From Table
)
Select Surname, Name, LoginDate, LoginTime
From Cte
Where RN = 1
请尝试此查询-
With MaxTimeStamp as
(
SELECT Surname, Name, Max(TIMESTAMP(LoginDate, LoginTime)) as LoginDateTime
FROM YourTable
group by Surname, Name
)
select c.Surname, c.Name, d.LoginDate, d.LoginTime,
from MaxTimeStamp c
Join YourTable d
on c.Surname = d.Surname
and c.Name = d.Name
and Date(c.LoginDateTime) = d.LoginDate
and Time(c.LoginDateTime) = d.LoginTime
为什么不是一个小组?我遗漏了什么 从表中选择名称、姓氏、登录名、maxLoginTime,其中按名称从表组中选择名称、姓氏、maxLoginDate,按名称从表组中选择姓氏、姓氏、maxLoginTime,按名称从姓氏组中选择姓氏、登录名、登录名 如果LoginDate不是日期或类似的数据类型,我想它应该运行
Br.我将其分为两部分,以查找每个用户的最新登录名并按进行分组。然后我再次加入数据以查找记录
select
dt.Surname
, dt.Name
, dt.LoginDate
, dt.LoginTime
from
dataTable dt
join
(select Surname, Name, MAX(LoginDate+LoginTime) ts from #temp group by surname, name) sub
on sub.Name = dt.Name
and sub.Surname = dt.Surname
and dt.LoginDate+dt.LoginTime = ts
WHERE
not sub.Name is null
您还可以通过再次拆分时间戳来完成此操作,而无需加入
select
sub.Surname
, sub.Name
, LEFT(ts,10) LoginDate
, RIGHT(ts,5) LoginTime
from
(select Surname, Name, MAX(LoginDate+LoginTime) ts from #temp group by surname, name) sub
您使用的是什么sql平台?Sql Server?我的SQL?神谕等等,LoginDate和LoginTime是什么数据类型?如果它们是一个字段作为DateTime,那就容易多了……这是在AS400上,不幸的是,日期和时间字段被定义为字符而不是日期或时间。我知道这是一个糟糕的设计,但这就是我必须处理的问题。如果以这种方式工作,我们的生活就会变得容易多了凉的很高兴知道它在Oracle中工作。谢谢你增加了我的甲骨文词汇量。
select
sub.Surname
, sub.Name
, LEFT(ts,10) LoginDate
, RIGHT(ts,5) LoginTime
from
(select Surname, Name, MAX(LoginDate+LoginTime) ts from #temp group by surname, name) sub