Reputation: 352
I am having trouble with a SQL query; I am trying to get the last service date of each 'asset'.
I am trying to use a left join with a subquery with a limit to 1.
Here are my tables:
lctn_test
testID, cleintID
1, 34
2, 34
srvc_test
srvcTestID, testID, serviceDate, servicePassed
1, 1, 2018-05-19 03:23:53, 1
2, 1, 2018-05-19 11:46:49, 1
3, 2, 2018-05-19 11:47:24, 1
and here is what I have tried (as well as a few variations)
SELECT
lctn.testID AS assetID, lctn.ClientID,
srvc_test.serviceDate, srvc_test.servicePassed
FROM
lctn_test AS lctn
LEFT JOIN
srvc_test ON lctn.testID = (SELECT srvc_test.testID
FROM srvc_test
WHERE srvc_test.testID = lctn.testID
ORDER BY srvc_test.serviceDate DESC
LIMIT 1)
WHERE
lctn.ClientID = 34
ORDER BY
assetID
What I expected to get:
assetID, ClientID, serviceDate, servicePassed
1, 34, 2018-05-19 11:46:49, 1
2, 34, 2018-05-19 11:47:24, 1
but this is what I actually get:
assetID, ClientID, serviceDate, servicePassed
1, 34, 2018-05-19 03:23:53, 1
1, 34, 2018-05-19 11:46:49, 1
1, 34, 2018-05-19 11:47:24, 1
2, 34, 2018-05-19 03:23:53, 1
2, 34, 2018-05-19 11:46:49, 1
2, 34, 2018-05-19 11:47:24, 1
I am still learning SQL (mysql) and for the life of me I can't see the issue; I am betting it is a noob mistake but I just don't see it.
Upvotes: 0
Views: 4977
Reputation: 86715
You have a LEFT JOIN b ON a.id = (sub-query)
You should have a LEFT JOIN b ON b.id = (sub-query)
SELECT lctn.testID AS assetID, lctn.ClientID, srvc_test.serviceDate, srvc_test.servicePassed
FROM lctn_test AS lctn
LEFT JOIN srvc_test ON srvc_test.srvcTestID = (
SELECT srvc_test.srvcTestID
FROM srvc_test
WHERE srvc_test.testID = lctn.testID
ORDER BY srvc_test.serviceDate DESC
LIMIT 1)
WHERE lctn.ClientID = 34
ORDER BY assetID
Upvotes: 2
Reputation: 31792
If you want exactly one row per join you should use a UNIQUE (or PRIMARY) KEY of the joined table in the ON clause. That is probably srvc_test.srvcTestID
.
SELECT lctn.testID AS assetID, lctn.ClientID, srvc_test.serviceDate, srvc_test.servicePassed
FROM lctn_test AS lctn
LEFT JOIN srvc_test ON srvc_test.srvcTestID = (
SELECT srvc_test.srvcTestID
FROM srvc_test
WHERE srvc_test.testID = lctn.testID
ORDER BY srvc_test.serviceDate DESC
LIMIT 1)
WHERE lctn.ClientID = 34
ORDER BY assetID
Upvotes: 1
Reputation: 1269853
Your query is missing the actual join
condition:
SELECT lctn.testID AS assetID, lctn.ClientID, srvc_test.serviceDate, srvc_test.servicePassed
FROM lctn_test lctn LEFT JOIN
srvc_test st
ON st.testID = lctn.testID AND
st.testID = (SELECT st2.testID
FROM srvc_test st2
WHERE st2.testID = st.testID
ORDER BY st.serviceDate DESC
LIMIT 1
)
WHERE lctn.ClientID = 34
ORDER BY assetID;
I switched the correlation conditions to be based on srvc_test
rather than lctn_test
. This doesn't really make a difference. I just find it simpler to be referring to a single table for this purpose.
Upvotes: 0