У меня возникают проблемы с SQL-запросом; Я пытаюсь получить последнюю дату службы каждого "актива".
Я пытаюсь использовать левое соединение с подзапросом с лимитом до 1.
Вот мои таблицы:
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
и вот что я пробовал (а также несколько вариантов)
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
Что я ожидал получить:
assetID, ClientID, serviceDate, servicePassed
1, 34, 2018-05-19 11:46:49, 1
2, 34, 2018-05-19 11:47:24, 1
но это то, что я действительно получаю:
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
Я все еще изучаю SQL (mysql), и для жизни меня не вижу проблемы; Я держу пари, что это ошибка, но я просто этого не вижу.
Если вы хотите ровно одну строку за соединение, вы должны использовать UNIQUE (или PRIMARY) KEY объединенной таблицы в предложении ON. Вероятно, это 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
У вас a LEFT JOIN b ON a.id = (sub-query)
У вас должен быть 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
В вашем запросе отсутствует фактическое условие join
:
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;
Я переключил условия корреляции на основе srvc_test
а не lctn_test
. Это не имеет особого значения. Я просто считаю, что для этой цели проще ссылаться на одну таблицу.
srvcTestID
вместоtestID
.