SQL查找最新的行使用GROUP BY

时间:2014-07-01 15:53:30

标签: sql

SQL新手听到撕裂我的头发试图解决这个问题!我有一个类似的问题。

我有以下数据,并且所有字段都被定义为CHARACTER - 遗憾的是没有日期或时间,原因是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    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显示为单独的输出中的字段,因为它们不包含在我使用的任何GROUP BY中。

是否有人能够告诉我如何做到这一点,因为我还没有得到很多头发:)

5 个答案:

答案 0 :(得分:2)

尝试此查询 -

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

答案 1 :(得分:0)

您不是使用group by执行此操作。以下是使用not exists的方法:

select t.*
from table t
where not exists (select 1
                  from table t2
                  where t2.name = t.name and t2.surname = t.surname and
                        (t2.logindate > t.logindate or
                         t2.logindate = t.logindate and
                         t2.logintime > t.logintime
                 );

这会将查询转换为:“从表中获取所有行,其中没有具有相同名称的行和稍后登录的行。”如果登录信息存储为单个日期时间,则会更简单。

此外,上述内容几乎适用于所有SQL数据库。许多数据库都支持窗口函数,也可用于此问题。

答案 2 :(得分:0)

除了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

答案 3 :(得分:0)

为什么不是一群人?我错过了什么?

从表格中选择姓名,姓氏,登录日期,最大值(登录时间),其中(姓名,姓氏,登录日期)(按名称,姓氏,姓名,姓名,姓名,姓名,最大值(登录日期))按名称,姓氏,登录日期分组

如果LoginDate不是日期或类似的数据类型,它应该运行我猜...

答案 4 :(得分:0)

我已将其拆分为两部分,以便为每个用户找到最新的登录信息并按分组执行。然后我再次加入数据以查找记录。

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