2014-05-04 61 views
0

我有一个主键和一个'第二'键的数据库中的表。第二个键可以在表中出现多次,但通常我只想返回第二个键的最近一行。我有一个现有的查询可以在下面使用,但我觉得这很丑陋,应该有一个更简单的方法来做到这一点,而不是创建一个表变量,通过一个循环,并在每次通过时插入1行到表变量循环。我是否让这太难?使用多个键优化SQL查询

declare @RowCnt int 
declare @MaxRows int 
declare @secondID as uniqueidentifier 
DECLARE @retList TABLE(
firstGUID uniqueidentifier, 
secondGUID uniqueidentifier, 
name nvarchar(50), 
DateCreated datetime 
) 

select @RowCnt = 1 

declare @Import table (rownum int IDENTITY (1, 1) Primary key NOT NULL , secondGUID uniqueidentifier) 
insert into @Import (secondGUID) SELECT DISTINCT dbo.TestTable.secondGUID FROM dbo.TestTable 

select @MaxRows=count(*) from @Import 
while @RowCnt <= @MaxRows 
begin 
    select @secondID=secondGUID from @Import where rownum = @RowCnt 

    INSERT INTO @retList 
     SELECT  TOP (1) firstGUID,secondGUID,name,datecreated 
     FROM   dbo.TestTable 
     WHERE dbo.TestTable.secondGUID = @secondID 
     ORDER BY DateCreated Desc 

    Set @RowCnt = @RowCnt + 1 
END 

select * from @retList 

编辑: 例如,假设表中有这些值

firstGUID        secondGUID        Name  DateCreated 
    EAD50999-E9B1-43F0-9FA6-615405FA5A9A  6163B6ED-6AF4-494E-ACE6-184F4804847B Test1 2014-04-11 15:12:36.303 
    A9645486-1021-4E98-92AC-1205CC3FB9D3  6163B6ED-6AF4-494E-ACE6-184F4804847B Test2 2014-04-10 15:21:46.087 
    DEE375BB-BFAF-44BE-AC64-06D7702E2ACB  3BD0A2F0-4E44-43B9-BD24-003B518609C7 Test3 
2014-04-11 15:22:37.097 

我只想要返回的测试1和Test3的行。

+0

如果“第二”键可出现在表中的多行上,这不是关键。无论是主钥匙还是备用钥匙,作为钥匙,它必须是唯一的。 –

+0

我不是争论这一点,这就是为什么我在报价中。这是一个关键,因为我希望我的查询的响应只有一个返回该键的结果(所以它在查询中是唯一的),但不是,它在表中不是唯一的。因此复杂的查询。 – Phil

+0

严肃地说,当在关系数据库中使用“key”这个词时,它具有明确而明确的含义。如果你在这里选择了另外一个词,你会更好地理解。 –

回答

2

你可以使用SqlServer的分析功能:

select firstGUID, secondGUID, name, datecreated 
from (select t.*, 
      rank() over (partition by secondGUID order by datecreated desc) r 
     from TestTable t) ilv 
where r=1 
+0

这可以工作(谢谢!),因为它返回与我原始查询相同的值,但分析函数对我来说是一个全新的领域。这比我上面的设置更快/更好吗? – Phil

+0

@Phil:我希望*它会更快,因为它只涉及一遍表格。 –

1

我不是100%确定我明白你在问什么,但它听起来像你只想选择包含max DateCreated的行。这样做的方式,一般是由子句使用一组子查询,例如:

select tt.* 
from TestTable tt 
join (
    select firstguid, max(DateCreated) as maxdate 
    from TestTable 
    group by firstguid 
) gtmp on tt.firstguid = gtmp.firstguid and tt.dateCreated = gtmp.maxdate 
加入
+0

为每个'secondguid'创建的最大日期。意思是我可以有3行,每行都有唯一的'firstguid'值,但是2具有相同的'secondguid'值。我希望我的查询返回2行。返回的重复'secondguid'行是最近一次。 – Phil

+0

你失去了我在“2排回”。如果您可以编辑您的问题并添加一些表示您拥有的数据以及您想要制作的数据,那么提出解决方案会更容易。 – thebjorn

+0

查看我添加的修改 – Phil