Это решение является адаптацией от another SO solution, спасибо RageZ для размещения этой связанной/аналогичный вопрос.
ПРИМЕЧАНИЕ
Это решение кажется удовлетворительным для случая использования Джастина. В зависимости от вашего варианта использования вы можете проверить решения Bill Karwin или David Andres в этой публикации. Решение Билла имеет мой голос! Посмотрите, почему, поскольку я поставил оба вопроса рядом друг с другом ;-)
Преимущество моего решения в том, что оно возвращает одну запись для категории_ид (информация из таблицы элементов «свернута»). Основным недостатком моего решения является отсутствие читаемости и растущая сложность, так как количество желаемых строк растет (скажем, 6 строк для каждой категории, а не 6). Кроме того, это может быть немного медленнее по мере роста количества строк в таблице элементов.(Независимо от того, что все решения будут лучше работать с меньшим количеством допустимых строк в таблице элементов, и поэтому рекомендуется либо периодически удалять, либо перемещать старые элементы и/или вводить флаг, чтобы помочь SQL отфильтровывать строки раньше)
Первая попытка (не работает !!!) ...
проблема с этим подходом в том, что подзапрос будет [по праву, но плохо для нас] производят очень много строк, на основе декартовых продуктов, определенных по самоклеящимся соединениям ...
SELECT id, CategoryName(?), tblFourImages.*
FROM category
JOIN (
SELECT i1.category_id, i1.image as Image1, i2.image AS Image2, i3.image AS Image3, i4.image AS Image4
FROM item AS i1
LEFT JOIN item AS i2 ON i1.category_id = i2.category_id AND i1.date_listed > i2.date_listed
LEFT JOIN item AS i3 ON i2.category_id = i3.category_id AND i2.date_listed > i3.date_listed
LEFT JOIN item AS i4 ON i3.category_id = i4.category_id AND i3.date_listed > i4.date_listed
) AS tblFourImages ON tblFourImages.category_id = category.id
--WHERE here_some_addtional l criteria if needed
ORDER BY id ASC;
Вторая попытка. (работает нормально!)
Предложение WHERE, добавленное для подзапроса, заставляя указанную дату быть последней, второй по последнему слову, наиболее поздней и т. Д. Для i1, i2, i3 и т. Д. Соответственно (а также для null случаях, когда для данного идентификатора категории имеется менее 4 элементов). Кроме того, были добавлены несвязанные предложения фильтра, чтобы запретить показ записей, которые «проданы» или записи, которые не имеют изображения (добавленные требования)
В этой логике делается предположение, что нет нумерованных значений даты (для данной категории_id) , В противном случае такие случаи создавали бы повторяющиеся строки. Фактически это использование указанной даты является версией монотонно увеличенного первичного ключа, как определено/требуется в решении Билла.
SELECT id, CategoryName, tblFourImages.*
FROM category
JOIN (
SELECT i1.category_id, i1.image as Image1, i2.image AS Image2, i3.image AS Image3, i4.image AS Image4, i4.date_listed
FROM item AS i1
LEFT JOIN item AS i2 ON i1.category_id = i2.category_id AND i1.date_listed > i2.date_listed AND i2.sold = FALSE AND i2.image IS NOT NULL
AND i1.sold = FALSE AND i1.image IS NOT NULL
LEFT JOIN item AS i3 ON i2.category_id = i3.category_id AND i2.date_listed > i3.date_listed AND i3.sold = FALSE AND i3.image IS NOT NULL
LEFT JOIN item AS i4 ON i3.category_id = i4.category_id AND i3.date_listed > i4.date_listed AND i4.sold = FALSE AND i4.image IS NOT NULL
WHERE NOT EXISTS (SELECT * FROM item WHERE category_id = i1.category_id AND date_listed > i1.date_listed)
AND (i2.image IS NULL OR (NOT EXISTS (SELECT * FROM item WHERE category_id = i1.category_id AND date_listed > i2.date_listed AND date_listed <> i1.date_listed)))
AND (i3.image IS NULL OR (NOT EXISTS (SELECT * FROM item WHERE category_id = i1.category_id AND date_listed > i3.date_listed AND date_listed <> i1.date_listed AND date_listed <> i2.date_listed)))
AND (i4.image IS NULL OR (NOT EXISTS (SELECT * FROM item WHERE category_id = i1.category_id AND date_listed > i4.date_listed AND date_listed <> i1.date_listed AND date_listed <> i2.date_listed AND date_listed <> i3.date_listed)))
) AS tblFourImages ON tblFourImages.category_id = category.id
--WHERE --
ORDER BY id ASC;
Теперь ... сравнить следующую команду, где я ввести item_id ключ и использовать решение Билла предоставить список их для «внешнего» запроса. Вы можете понять, почему подход Билла лучше ...
SELECT id, CategoryName, image, date_listed, item_id
FROM item I
LEFT OUTER JOIN category C ON C.id = I.category_id
WHERE I.item_id IN
(
SELECT i1.item_id
FROM item i1
LEFT OUTER JOIN item i2
ON (i1.category_id = i2.category_id AND i1.item_id < i2.item_id
AND i1.sold = 'N' AND i2.sold = 'N'
AND i1.image <> '' AND i2.image <> ''
)
GROUP BY i1.item_id
HAVING COUNT(*) < 4
)
ORDER BY category_id, item_id DESC
Я должен копать свою книгу SQL ^^ – RageZ
Как «статические» являются вашими категориями? Это список, который меняется время от времени или постоянный? –
ха-ха. рыть копать! : D – justinl