SQL查询返回最新日期以及表中的其他信息

时间:2014-05-05 20:54:07

标签: sql sql-server

我有5个与此查询相关的表和列:

  • 狗(ID,CallName,Color,Sex,Chipnumber,BreedID)
  • 品种(身份证,姓名)
  • 状态(ID,状态,OwnedOnPremises)
  • DogsStatus(ID,DogsID,StatusID,StatusDate,Note,ContactsID)
  • 联系人(ID,姓名)

我想要所有狗的结果和他们最好的状态。对于测试,我使用以下记录:

  • Dogs(251,Tank,Fawn,M,14410784,23)(266,Bonnie,Brindle,14964070,23)
  • 品种(23,獒犬)
  • 状态(3,已售出)(4,离开)(7,已购买)(9,已退回)
  • DogsStatus(29,251,3,2013-10-12,5)(39,251,9,1013-11-10,17)(146,251,4,2014-01-10,7)( 40,266,7,2013-10-10,1)
  • 联系人(1,人1)(5,人5)(7,人7)(17,人17)

到目前为止,我有:

SELECT 
    d.CallName, b.Name AS 'Breed', d.Color, d.Sex, d.ChipNumber
FROM 
    Dogs d
JOIN 
   (SELECT 
        DogsID, MAX(StatusDate) as MaxStatusDate 
    FROM DogsStatus 
    GROUP BY DogsID) mds ON mds.DogsID = d.ID
JOIN 
   Breeds b ON b.ID = d.BreedID

这将返回2个唯一记录(1个用于Tank,1个用于Bonnie),但每当我尝试获取任何其他DogsStatus和/或状态信息时,我要么只返回一个狗记录,要么全部3个Tanks DogsStatus记录。

提前致谢。

3 个答案:

答案 0 :(得分:1)

您需要将MaxStatusDate加入DogsStatus表格。这样,在您拥有多种状态的情况下,您将只获得最新状态。 像

这样的东西
SELECT 
    d.CallName, b.Name AS 'Breed', d.Color, d.Sex, d.ChipNumber
FROM 
    Dogs d
innner join DogsStatus ds
  ON d.dogsid = ds.dogs_id
JOIN 
   (SELECT 
        DogsID, MAX(StatusDate) as MaxStatusDate 
    FROM DogsStatus 
    GROUP BY DogsID) mds ON mds.DogsID = d.ID
JOIN 
   Breeds b ON b.ID = d.BreedID
   AND mds.maxstatusdate = ds.statusdate

这些方面的东西。

答案 1 :(得分:0)

你很亲密。您只需返回DogStatus表即可获得完整记录。请注意,我更喜欢CTE,但您现有的派生表(子查询)方法也可以正常工作:

With StatusDates As
(

    SELECT 
        DogsID, MAX(StatusDate) as StatusDate 
    FROM DogsStatus 
    GROUP BY DogsID
), CurrentStatus As 
(
    SELECT ds.*
    FROM DogStatus ds
    INNER JOIN StatusDates sd ON sd.DogsID = ds.DogsID AND ds.StatusDate = sd.StatusDate
)
SELECT d.Name, b.Name As Breed, d.Color, d.Sex, d.ChipNumber
    , s.Status, cs.StatusDate, c.Name As ContactName
FROM Dogs d
INNER JOIN CurrentStatus cs ON cs.DogsID = d.ID
INNER JOIN Breed b on b.ID = d.BreedID
INNER JOIN Status s on s.ID = cs.StatusID
INNER JOIN Contact c on c.ID = cs.ContactID

您可能希望对其中一些使用LEFT连接,然后更改选择列表以使用coalesce()表达式来清理NULL。

答案 2 :(得分:0)

会是这样的,我相信你能够根据自己的需要调整它:

;with x as (
  select *, row_number() over(partition by d.DogsId order by StatusDate desc) as rn
  from Dogs d
  inner join DogsStatus on d.DogsId = ds.DogsId
)
select *
from x
where rn = 1