evibesmusic
asked on
How to return multiple query results based on the date column in one of two tables?
Experts,
I have a situation in which I am querying two tables with the following:
$sql = "SELECT * FROM photos_clinicians c, photos p WHERE c.Department='$Department' AND c.Site='$Site' AND c.ResourceID=p.EmployeeID ORDER BY p.LastName";
The problem is that the table 'photos p' allows for multiple entries that are the same, with the exception of the 'p.date' column.
Example of 'photos' table:
FirstName | LastName | EmployeeID | Date
Steve | Smith | 1234567 | 01/01/09
Steve | Smith | 1234567 | 01/01/10
Bob | Johnson | 7985632 | 02/01/09
John | Thomas | 5986347 | 05/06/10
Bob | Johnson | 7985632 | 03/02/10
I would like to limit the output of my query based on 'p.Date' so that only the latest entry according to 'p.Date' is printed to the screen without losing the rest of the query data?
So if the query above were modified my result set would look like:
Steve | Smith | 1234567 | 01/01/10
John | Thomas | 5986347 | 05/06/10
Bob | Johnson | 7985632 | 03/02/10
When I use 'LIMIT 1' in the query, the query only shows one total result when there could be hundreds. Can I use some form of 'Distinct' in my query to get the results I am looking for?
Any suggestions?
I have a situation in which I am querying two tables with the following:
$sql = "SELECT * FROM photos_clinicians c, photos p WHERE c.Department='$Department'
The problem is that the table 'photos p' allows for multiple entries that are the same, with the exception of the 'p.date' column.
Example of 'photos' table:
FirstName | LastName | EmployeeID | Date
Steve | Smith | 1234567 | 01/01/09
Steve | Smith | 1234567 | 01/01/10
Bob | Johnson | 7985632 | 02/01/09
John | Thomas | 5986347 | 05/06/10
Bob | Johnson | 7985632 | 03/02/10
I would like to limit the output of my query based on 'p.Date' so that only the latest entry according to 'p.Date' is printed to the screen without losing the rest of the query data?
So if the query above were modified my result set would look like:
Steve | Smith | 1234567 | 01/01/10
John | Thomas | 5986347 | 05/06/10
Bob | Johnson | 7985632 | 03/02/10
When I use 'LIMIT 1' in the query, the query only shows one total result when there could be hundreds. Can I use some form of 'Distinct' in my query to get the results I am looking for?
Any suggestions?
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
$sql = "SELECT p.FirstName, p.LastName, p.EmployeeID, MIN(p.Date) AS Date FROM photos_clinicians c, photos p WHERE c.Department='$Department' AND c.Site='$Site' AND c.ResourceID=p.EmployeeID GROUP BY p.FirstName, p.LastName, p.EmployeeID ORDER BY p.LastName";
i am thinking of such a query, not sure if we can make it run though:
select * from (
SELECT c.*, p.*, @rownum:=iif(@preEmpID=p.E mployeeID, 1,0)*@rown um + 1 as rank, @preEmpID=p.EmployeeID
FROM photos_clinicians c, photos p, (SELECT @rownum := 0, @preEmpID=0) r
WHERE c.Department='$Department' AND c.Site='$Site' AND c.ResourceID=p.EmployeeID
ORDER BY p.EmployeeID, Date Desc
) x where rank = 1
ORDER BY LastName
idea is implementing rank function here, on each record rank is calculated. if empid does not chnage it increments 1 otherwise reset to 0. then another one selects records with rank=1
select * from (
SELECT c.*, p.*, @rownum:=iif(@preEmpID=p.E
FROM photos_clinicians c, photos p, (SELECT @rownum := 0, @preEmpID=0) r
WHERE c.Department='$Department'
ORDER BY p.EmployeeID, Date Desc
) x where rank = 1
ORDER BY LastName
idea is implementing rank function here, on each record rank is calculated. if empid does not chnage it increments 1 otherwise reset to 0. then another one selects records with rank=1
or just replace "photos p" in your original query with
(
select p1.* from Photos p1, (select EmployeeID, max(Date) as maxDate from photos) p2
where p1.EmployeeID=p2.EmployeeI D and p1.date=p2.maxDate
) p
so your solution becomes
(
select p1.* from Photos p1, (select EmployeeID, max(Date) as maxDate from photos) p2
where p1.EmployeeID=p2.EmployeeI
) p
so your solution becomes
$sql = "SELECT * FROM photos_clinicians c, (select p1.* from Photos p1, (select EmployeeID, max(Date) as maxDate from photos) p2 where p1.EmployeeID=p2.EmployeeID and p1.date=p2.maxDate) p WHERE c.Department='$Department' AND c.Site='$Site' AND c.ResourceID=p.EmployeeID ORDER BY p.LastName";
My apologies, my suggestion should have been:
$sql = "SELECT p.FirstName, p.LastName, p.EmployeeID, MAX(p.Date) AS Date FROM photos_clinicians c, photos p WHERE c.Department='$Department' AND c.Site='$Site' AND c.ResourceID=p.EmployeeID GROUP BY p.FirstName, p.LastName, p.EmployeeID ORDER BY p.LastName";
Patrick,
I think the listed sample result is a sample only.
I took "without losing the rest of the query data" to mean other columns from both tables.. who knows!
I think the listed sample result is a sample only.
I took "without losing the rest of the query data" to mean other columns from both tables.. who knows!
ASKER
@cyberkiwi:
Thank you for your help. I've used your query with one modification made to it. See below:
I made the modification to your call to 'p.ID' as yes, there is a column 'ID' in both tables but, in some cases the ID of each row is not indicative of the latest entry. Thus I changed 'p.ID' to 'p.Date' as the I really wanted to pull the information based on the latest date. Sorry if I confused the issue in my original post.
Either way...CHEERS! Thanks for your help.
Thank you for your help. I've used your query with one modification made to it. See below:
I made the modification to your call to 'p.ID' as yes, there is a column 'ID' in both tables but, in some cases the ID of each row is not indicative of the latest entry. Thus I changed 'p.ID' to 'p.Date' as the I really wanted to pull the information based on the latest date. Sorry if I confused the issue in my original post.
Either way...CHEERS! Thanks for your help.
$sql = "
SELECT * FROM photos_clinicians c, photos p
WHERE c.Department='$Department' AND c.Site='$Site' AND c.ResourceID=p.EmployeeID
AND p.Date in (
SELECT MAX(p.Date) FROM photos_clinicians c, photos p
WHERE c.Department='$Department' AND c.Site='$Site' AND c.ResourceID=p.EmployeeID
GROUP BY c.ResourceID
)
ORDER BY p.LastName
";
ASKER
Cheers to all that attempted to help me with this issue.
It gives you the wrong result though (may still get duplicates), if it is not the unique ID.
Let me see (you should list all the columns you need, but c.*, p.* is equal to the list without the x subquery)
$sql = "
SELECT c.*, p.*
FROM (
SELECT c.ResourceID, MAX(p.Date) pDate FROM photos_clinicians c, photos p
WHERE c.Department='$Department' AND c.Site='$Site' AND c.ResourceID=p.EmployeeID
GROUP BY c.ResourceID
) x
inner join photos_clinicians c on c.resourceid=x.resourceid
inner join photos p on c.ResourceID=p.EmployeeID and p.date = x.pdate
WHERE c.Department='$Department' AND c.Site='$Site'
ORDER BY p.LastName
";
Let me see (you should list all the columns you need, but c.*, p.* is equal to the list without the x subquery)
$sql = "
SELECT c.*, p.*
FROM (
SELECT c.ResourceID, MAX(p.Date) pDate FROM photos_clinicians c, photos p
WHERE c.Department='$Department'
GROUP BY c.ResourceID
) x
inner join photos_clinicians c on c.resourceid=x.resourceid
inner join photos p on c.ResourceID=p.EmployeeID and p.date = x.pdate
WHERE c.Department='$Department'
ORDER BY p.LastName
";
ASKER
@cyberkiwi:
I have tested the query specifically on entries in the db that would give me duplicate results and they don't appear? Would the use of 'MAX(p.Date)' only return results where the Maximum date has been established?
I have tested the query specifically on entries in the db that would give me duplicate results and they don't appear? Would the use of 'MAX(p.Date)' only return results where the Maximum date has been established?
FirstName | LastName | EmployeeID | Date
Steve | Smith | 1234567 | 01/01/09
Steve | Smith | 1234567 | 01/01/10 ***
Bob | Johnson | 7985632 | 01/01/10 <<<<
John | Thomas | 5986347 | 05/06/10 ***
Bob | Johnson | 7985632 | 03/02/10 ***
The subquery returns a list of Max dates for any resource, so it returns the dates marked in ***
But see the one marked <<<<.
It will get returned as well because there is no correlation between max date and outer query.
Steve | Smith | 1234567 | 01/01/09
Steve | Smith | 1234567 | 01/01/10 ***
Bob | Johnson | 7985632 | 01/01/10 <<<<
John | Thomas | 5986347 | 05/06/10 ***
Bob | Johnson | 7985632 | 03/02/10 ***
The subquery returns a list of Max dates for any resource, so it returns the dates marked in ***
But see the one marked <<<<.
It will get returned as well because there is no correlation between max date and outer query.
ASKER
@cyberkiwi:
So with that said, you would like me to try the query posted here: 11/11/10 02:54 PM, ID: 34116556
And - if so, should I list all of the columns I would like data from rather than using the wildcard * ?
So with that said, you would like me to try the query posted here: 11/11/10 02:54 PM, ID: 34116556
And - if so, should I list all of the columns I would like data from rather than using the wildcard * ?
Yes the new query would work correctly (if there is no error to it!)
And yes, * is really good for testing and stuff, but do expand it when you can.
And yes, * is really good for testing and stuff, but do expand it when you can.
ASKER
@cyberkiwi:
Great! Thank you very much. I will use the second query and expand upon the wild card...I have already tested the query and it works without errors...had to correct some of the spelling for the columns but other than that we are good to go.
Thanks Cyberkiwi...I'd award more points if I could. I'm full of odd questions so, check back if you want more points.
Cheers!
Great! Thank you very much. I will use the second query and expand upon the wild card...I have already tested the query and it works without errors...had to correct some of the spelling for the columns but other than that we are good to go.
Thanks Cyberkiwi...I'd award more points if I could. I'm full of odd questions so, check back if you want more points.
Cheers!