SQL:Оператор для отображения 1 дочерней записи для каждого родителя в отношениях «один ко многим»
-
23-08-2019 - |
Вопрос
У меня есть 2 таблицы: таблица продуктов и таблица изображений.Товары могут иметь более 1 изображения в каждой записи.Мне нужен оператор SQL, который будет отображать одно изображение для каждого продукта, а не все изображения для каждого продукта.
Уменьшенный пример моих текущих усилий:
SELECT Product.RefCode, Img.ImgPath
FROM Product INNER JOIN (
SELECT ProductImg.ImgPath, ProductImg.PrdFK
FROM ProductImg
LIMIT 0,1) AS Img ON Product.PrdID = Img.PrdFK;
Приведенный выше пример возвращает 0 результатов, однако, если я удалю LIMIT 0,1 из Sub SELECT, я получу полный список всех продуктов и всех изображений.
Я просто хочу, чтобы была возвращена 1 запись изображения для каждой записи продукта.
Я переработал код «программиста» для MySQL, и он работает нормально.
SELECT Product.RefCode,
(Select ProductImg.ImgPath
From ProductImg
Where Product.PrdID = Img.PrdFK LIMIT 0,1) AS ImgPath
FROM Products
По какой-то причине при попытке решения «Билла Карвина» загрузка сервера длилась долго.
Решение
Это должно работать:
SELECT Product.RefCode,
(Select Img.ImgPath
From ProductImg
Where Product.PrdID = Img.PrdFK LIMIT 0,1) As ImgPath
FROM Product
Если у вас есть способ определить, какое изображение должно вернуть выбранное, вы можете добавить «где» и, возможно, «Порядок» в подвыбор.
В следующем примере мы получим только последнее из активных изображений.
SELECT Product.RefCode,
(Select Img.ImgPath
From ProductImg
Where Product.PrdID = Img.PrdFK
And IsActive = 1
Order By EntryDate Desc LIMIT 0,1) As ImgPath
FROM Product
Отредактировано и исправлено «Топ 1» на «Лимит 0,1».
Другие советы
MySQL имеет здесь некоторую гибкость.Вы можете использовать GROUP BY, чтобы ограничить результат одной строкой для каждого продукта, и тогда MySQL произвольно выберет, какое изображение.На практике обычно изображение сначала физически сохраняется в базе данных, но вы не имеете над этим никакого контроля.
SELECT p.RefCode, i.ImgPath
FROM Product p INNER JOIN ProductImg i
ON (p.PrdID = i.PrdFK)
GROUP BY p.PrdID;
Если ты хочешь 1 специфический изображение для каждого продукта, есть способы сделать это.Вам необходимо включить это в свои требования.:-)
Если у вас есть столбец ID в таблице изображений, это должно работать (независимо от продукта или версии SQL) –
SELECT p.RefCode, i1.ImgPath FROM Product p INNER JOIN ProductImg i1 ON p.PrdId = i1.PrdFk LEFT JOIN ProductImg i2 ON i1.PrdId = i2.PrdId AND i1.ImgId < i2.ImgId WHERE i2.ImgId IS NULL
Вам нужен флаг в таблице изображений, указывающий, является ли это изображение основным для отображения.Есть способы получить произвольное изображение, но я думаю, что лучше убедиться, что вы извлекаете правильное изображение.