0

我手上有一个有点乱的表,有两个字段,一个日期字段和一个时间字段,它们都是字符串。我需要做的是从这些字段中获取最短日期,或者如果没有附加日期/时间,则只获取记录本身。以下是一些示例数据:

ID     First     Last     Date         Time
1      Joe       Smith    2013-09-06   04:00
1      Joe       Smith    2013-09-06   02:00
2      Jack      Jones            
3      John      Jack     2013-09-05   06:00
3      John      Jack     2013-09-15   15:00

我想从查询中得到以下信息:

ID     First     Last     Date         Time
1      Joe       Smith    2013-09-06   02:00
2      Jack      Jones            
3      John      Jack     2013-09-05   06:00

ID 1 和 3 的最小日期/时间,然后返回 ID 2,因为他没有日期/时间。我想出了下面的查询,它给我的 ID 1 和 3 正是我想要的:

SELECT *
FROM test as t
where 
cast(t.date + ' ' + t.time as Datetime ) = (select top 1 cast(p.date + ' ' + p.time as Datetime ) as dtime from test as p where t.ID = p.ID order by dtime)

但它根本不返回第 2 行。我想有更好的方法来做到这一点。有任何想法吗?

4

3 回答 3

2

你可以这样做row_number()

select ID, First, Last, Date, Time
from (select t.*,
             row_number() over (partition by id order by date, time) as seqnum
      from test t
     ) t
where seqnum = 1;

尽管不建议将日期和时间存储为字符串,但您至少可以做到这一点。这些值使用 ISO 标准格式(或足够接近),因此字母排序与日期/时间排序相同。

于 2013-08-23T19:02:00.867 回答
1

假设[Date]and[Time]是我认为的类型,而不是字符串:

SELECT ID,[First],[Last],[Date],[Time] FROM 
(
  SELECT ID,[First],[Last],[Date],[Time],rn = ROW_NUMBER() 
    OVER (PARTITION BY ID ORDER BY [Date], [Time])
  FROM dbo.test
) AS t WHERE rn = 1;

例子:

DECLARE @x TABLE
(
  ID INT,
  [First] VARCHAR(32), 
  [Last] VARCHAR(32),
  [Date] DATE,
  [Time] TIME(0)
);

INSERT @x VALUES
(1,'Joe ','Smith','2013-09-06','04:00'),
(1,'Joe ','Smith','2013-09-06','02:00'),
(2,'Jack','Jones',NULL,         NULL  ),
(3,'John','Jack ','2013-09-05','06:00'),
(3,'John','Jack ','2013-09-15','15:00');

SELECT ID,[First],[Last],[Date],[Time] FROM 
(
  SELECT ID, [First],[Last],[Date],[Time],rn = ROW_NUMBER() 
    OVER (PARTITION BY ID ORDER BY [Date], [Time])
  FROM @x
) AS x WHERE rn = 1;

结果:

ID   First   Last    Date          Time
--   -----   -----   ----------    --------
1    Joe     Smith   2013-09-06    02:00:00
2    Jack    Jones   NULL          NULL            
3    John    Jack    2013-09-05    06:00:00
于 2013-08-23T19:50:35.730 回答
0

尝试:

SELECT 
   *
FROM 
   test as t
WHERE 
   CAST(t.date + ' ' + t.time as Datetime) = 
    (
     select top 1 cast(p.date + ' ' + p.time as Datetime ) as dtime 
     from test as p 
     where t.ID = p.ID 
     order by dtime
    )
OR (t.date='' AND t.time='')
于 2013-08-23T19:25:00.083 回答