I have 5 tables and columns pertinent to this query:
I am wanting a result of all dogs and their LATEST status. For a test I am using the following records:
So far I have:
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
This will return 2 unique records (1 for Tank and 1 for Bonnie), but whenever I try to get any other of the DogsStatus and/or Status info, I either return only one dog record, or all 3 of Tanks DogsStatus records.
Thanks in advance.
You'll need to join your MaxStatusDate
to the DogsStatus
table. That way you will only get the most recent status, in the case where you have multiple statuses. Something like
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
Something along those lines.
You're close. You just need to go back to the DogStatus table to get that full record. Note that I prefer CTEs for this, but your existing derived table (subquery) approach works just fine, too:
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
You may want to use a LEFT join for some of those, and then change the select list to use coalesce() expressions to clean up the NULLs.
It would be something like this, I'm certain you'll be able to adapt it to your needs:
;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
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.