0

让我们考虑下表。

Id(PK, int) | DocDate(long) | Sender(varchar) | Recipient(varchar) | PeriodStart(long) | PeriodEnd(long)

对于每个Sender, Recipient, PerdiodStart,PeriodEnd我在不同的时间点写多个条目。所以DocDate不同。

现在我必须选择最新的 id DocDate、 foreach SenderRecipientPeriodStartPerdiodEnd。我自己找到的唯一解决方案是使用 CTE。

with prevFilter as (
    select   max(DocDate), Sender, Recipient, PeriodStart, PeriodEnd
    from     Table
    group
    by       Sender, Recipient, PeriodStart, PeriodEnd
)
select   Id
from     Table t
inner
join     prevFilter pf
         on  pf.DocDate = t.DocDate 
         and pf.Sender = t.Sender 
         and pf.Recipient = t.Recipient
         and pf.PeriodStart = t.PeriodStart
         and pf.PeriodEnd = t.PeriodEnd

你现在可能会想,这个查询的性能很差,但我可以用聚集索引来改进它。

但我想知道,如果没有更快、更优雅的解决方案来解决这个问题。谁能提供一份?

4

4 回答 4

4

您可以使用 CTE 和ROW_NUMBER

with prevFilter as (
    select   Id, 
             RN = ROW_NUMBER() OVER(PARTITION BY Sender, Recipient, PerdiodStart, PeriodEnd
                                    ORDER BY DocDate DESC)
    from     Table
)
select   Id
from     prevFilter t
where RN = 1
于 2013-06-07T13:29:14.037 回答
1

DocDate您可以使用 SQL Server 排名函数来隔离每个组合的最高记录Sender,Recipient, PeriodStart, PeriodEnd,然后过滤:

Select * from (
select  *, row_number() over (partition by Sender, 
                             Recipient, PeriodStart, PeriodEnd
      order by DocDate desc) as ranker
from     Table
) where ranker = 1
于 2013-06-07T13:30:15.923 回答
1

Lamak 的想法是正确的,但也有一些错误。这个版本应该可以工作。

with prevFilter as (
select   Id, 
         RN = ROW_NUMBER() OVER(
             PARTITION BY Sender, Recipient, PeriodStart, PeriodEnd
             ORDER BY DocDate DESC)
from     Table
)
select   Id
from     prevFilter t
where RN = 1
于 2013-06-07T13:38:13.703 回答
0

您还可以使用:

SELECT *
FROM (
    SELECT DISTINCT Sender, Recipient, PeriodStart, PeriodEnd
    FROM YourTable t1
) t CROSS APPLY (
    SELECT TOP 1 Id
    FROM YourTable t2
    WHERE t2.Sender = t.Sender 
    AND t2.Recipient = t.Recipient
    AND t2.PeriodStart = t.PeriodStart
    AND t2.PeriodEnd = t.PeriodEnd
    ORDER BY DocDate DESC
) x

或者:

SELECT *
FROM YourTable t1
WHERE NOT EXISTS (
    SELECT *
    FROM YourTable t2
    WHERE t2.Sender = t1.Sender 
    AND t2.Recipient = t1.Recipient
    AND t2.PeriodStart = t1.PeriodStart
    AND t2.PeriodEnd = t1.PeriodEnd
    AND t2.DocDate>t1.DocDate
) 

拉兹万

于 2013-06-07T13:33:08.823 回答