0

我有一个包含以下行的表:

 NAME                        RFID                  ACTION    TIME       DATE

Kashif Islam            E2001026770D00742340248A    OUT  12:40:00   1/30/2013
Dr.Arshad Ali Shahid    E2001026770D0212267009D3    IN   13:52:00   1/30/2013
Qasim Mehmood           E2001026770D018223202774    IN   13:52:00   1/30/2013
M.Bilal Khan            E2001026770D009522402D80    IN   13:52:00   1/30/2013
Abdul Hameed            E2001026770D0181248019B8    IN   13:52:00   1/30/2013
Usman Tariq             E2001026770D00862570111D    IN   13:52:00   1/30/2013
Dr. Asif Gondal         E2001026770D012426600B32    IN   13:52:00   1/30/2013
Dr.Arshad Ali Shahid    E2001026770D0212267009D3    OUT  13:52:00   1/30/2013
Dr.Arshad Ali Shahid    E2001026770D0212267009D3    IN   13:53:00   1/30/2013
Dr.Arshad Ali Shahid    E2001026770D0212267009D3    OUT  13:53:00   1/30/2013
Dr.Arshad Ali Shahid    E2001026770D0212267009D3    IN   13:53:00   1/30/2013
Dr.Arshad Ali Shahid    E2001026770D0212267009D3    OUT  13:53:00   1/30/2013
Dr.Arshad Ali Shahid    E2001026770D0212267009D3    IN   13:54:00   1/30/2013
Dr.Arshad Ali Shahid    E2001026770D0212267009D3    OUT  13:54:00   1/30/2013
Aamir Hafeez            E2001026770D01952510155B    IN   13:55:00   1/30/2013
Amjad Ali Anjum         E2001026770D024125401476    IN   13:55:00   1/30/2013
Amjad Ali Anjum         E2001026770D024125401476    OUT  13:56:00   1/30/2013
Dr. Asif Gondal         E2001026770D012426600B32    OUT  13:56:00   1/30/2013
Arif Shah               E2001026770D01852370206D    IN   13:56:00   1/30/2013
Fida ul Hassan          E2001026770D02112720095C    IN   13:56:00   1/30/2013

现在我想获取ACTION每个人在给定日期的最新信息,例如:

    1/30/2013   13:56:00    OUT Amjad Ali Anjum
    1/30/2013   13:56:00    IN  Arif Shah
    1/30/2013   13:56:00    OUT Dr. Asif Gondal
    1/30/2013   13:54:00    OUT Dr.Arshad Ali Shahid
    1/30/2013   13:56:00    IN  Fida ul Hassan

我正在使用以下查询来获取它,但我没有得到正确的结果:

WITH CTE AS (
SELECT 
   row_number() over (partition by personname order by date) rn,
   date,action,time,
   personname

FROM
   AISDb)
SELECT date,time,action,
       personname
FROM CTE WHERE RN = 1 AND datestamp = '1/30/2013'
4

3 回答 3

8

我认为您只是将过滤器放在了错误的位置,并且 over() 子句中的 order by 都是错误的。

;WITH CTE AS (
  SELECT 
   row_number() over (partition by personname order by time DESC) rn,
   date,action,time,
   personname
FROM
   AISDb
WHERE datestamp = '20130130')
SELECT date,time,action,
       personname
FROM CTE WHERE RN = 1;

SQL小提琴演示

如果您需要在 IN/OUT 以某种方式同时记录的情况下打破平局,一种方法是打破平局,假设 OUT 最后发生:

;WITH CTE AS (
  SELECT 
   row_number() over (partition by personname order by time DESC, action DESC) rn,
   date,action,time,
   personname
FROM
   AISDb
WHERE datestamp = '20130130')
SELECT date,time,action,
       personname
FROM CTE WHERE RN = 1;

SQL小提琴演示

于 2013-04-23T16:52:50.617 回答
2

经典问题。一种可能的解决方案:

select w.* 
from w
inner join (
    select name, max(time) time
    from w
    where date = '2013-01-30'
    group by Name
) sel on w.Name = sel.Name 
     and w.Time = sel.Time
where w.date = '2013-01-30'

捎带 Aaron 的小提琴: http ://sqlfiddle.com/#!3/335e4/11

几点考虑:

  • 你真的应该一个字段来保存日期和时间。过滤、索引、排序,所有这些都更简单。
  • 如果您有 TIE(同一名称同时进行两个交易),此解决方案将同时带来两者。
于 2013-04-23T17:24:17.120 回答
-1

正如人们的回答表明您需要将日期/时间逻辑的顺序更改为 Desc 以便您首先获得最新的。另一件事是您仅在 CTE 中按人名进行分区,因此无论日期如何,1 值都将是最新值,然后您将日期限制在外部,因此您可能没有匹配的值。您可以通过几种方式解决此问题,但我只是将日期添加到分区逻辑中。

WITH    CTE AS 
(
        SELECT  row_number() over (partition by personname, [date]  order by [time] desc, rn desc) rn,
                [date],
                [action],
                [time],
                personname
        FROM   (Select  row_number() over (Order By (Select Null)) rn,
                        [date],
                        [action],
                        [time],
                        personname
                FROM    AISDb)
)
SELECT  [date],
        [action],
        [time],
        personname
FROM    CTE 
WHERE   RN = 1 
AND     datestamp = '1/30/2013'

为了绕过关系,我添加了一个嵌套表,该表根据(选择 Null)获取 row_number。这是一个 janky 解决方法,将获得默认排序。如果这不起作用,您将无法使用当前输入做您想做的事情,您应该添加一个标识列来捕获插入的顺序。

于 2013-04-23T17:56:10.157 回答