根据日期列为每个ID返回一行(SQL)

时间:2009-10-06 20:17:32

标签: sql tsql

DDL创建架构和数据。我正在寻找 where 语句,其中每个ID只返回一行,该行将是基于inserteddate列的最后一行。

结果将是John,5和Debbie,5

select Table1.Name, Table2.Rating
From table1 join table2 on table1.ID = table2.ID
where inserteddate = max(insertedate) 

..每个ID?看起来很简单,但我有脑筋。

DDL:

CREATE TABLE [dbo].[Table1](
    [Table1ID] [int] NULL,
    [Name] [varchar](50) NULL
)

CREATE TABLE [dbo].[Table2](
    [Table2ID] [int] NULL,
    [InsertedDate] [datetime] NULL,
    [Rating] [varchar](50) NULL
)

INSERT INTO [dbo].[Table1]([Table1ID], [Name])
SELECT 1, N'John' UNION ALL
SELECT 2, N'Debbie'
INSERT INTO [dbo].[Table2]([Table2ID], [InsertedDate], [Rating])
SELECT 1, '20090101 00:00:00.000', N'6' UNION ALL
SELECT 1, '20090401 00:00:00.000', N'5' UNION ALL
SELECT 2, '20090202 00:00:00.000', N'3' UNION ALL
SELECT 2, '20090303 00:00:00.000', N'5'

3 个答案:

答案 0 :(得分:0)

我确信有更好的方法,但这样做会:

CREATE TABLE #Table1(
    [Table1ID] [int] NULL,
    [Name] [varchar](50) NULL
)

CREATE TABLE #Table2(
    [Table2ID] [int] NULL,
    [InsertedDate] [datetime] NULL,
    [Rating] [varchar](50) NULL
)

INSERT INTO #Table1([Table1ID], [Name])
SELECT 1, N'John' UNION ALL
SELECT 2, N'Debbie'
INSERT INTO #Table2([Table2ID], [InsertedDate], [Rating])
SELECT 1, '20090101 00:00:00.000', N'6' UNION ALL
SELECT 1, '20090401 00:00:00.000', N'5' UNION ALL
SELECT 2, '20090202 00:00:00.000', N'3' UNION ALL
SELECT 2, '20090303 00:00:00.000', N'5'


select x.name, t2.rating
from 
(
select t1.table1id, t1.name, max(t2.inserteddate) as inserteddate
from #table1 t1
join
#table2 t2
on
t1.table1id = t2.table2id
group by t1.table1id, t1.name
) x
join
#table2 t2
on
x.table1id = t2.table2id
and 
x.inserteddate = t2.inserteddate

答案 1 :(得分:0)

select
    table1.name,
    table2.rating
from
    table1
    inner join table2 on 
        table2.id = (select top 1 t2.id from table2 t2 where table1.id = t2.id order by t2.inserteddate desc)
等等,table2没有主键?然后...

select
    table1.name,
    (select top 1 t2.rating 
    from table2 t2 
    where table1.id = t2.id order by t2.inserteddate desc) as last_rating
from
    table1

答案 2 :(得分:0)

这个怎么样:

SELECT 
  Table1.Name, Table2.Rating
FROM
  table1 
INNER JOIN 
  table2 ON table1.Table1ID = table2.Table2ID
WHERE
  inserteddate = (SELECT MAX(InsertedDate) 
                    FROM Table2 t2 
                   WHERE t2.Table2ID = Table2.Table2ID)

在这种情况下,InsertedDate列上的索引会非常有用!

或者,如果您使用的是SQL Server 2005及更高版本,您还可以使用带有ROW_NUMBER()和PARTITION OVER语句的CTE(公用表表达式),如下所示:

WITH HelperCTE AS
(
  SELECT
    Table1.Name, Table2.Rating,
    ROW_NUMBER() OVER(PARTITION BY Table1.Table1ID 
                      ORDER BY Table2.InsertedDate DESC) AS 'RowNum'
  FROM
    table1 
  INNER JOIN
    table2 ON table1.Table1ID = table2.Table2ID
)
SELECT Name, Rating FROM HelperCTE
WHERE RowNum = 1

这就像“临时”视图(CTE)一样创建并对由Table1ID分区的条目(每个单独的Table1ID的单独编号)进行编号,并按InsertedDate降序排序 - 因此对于每个唯一的Table1ID,最近的输入将有RowNum = 1。

马克