#mysql #sql
#mysql #sql
Вопрос:
У меня следующий SQL-запрос:
SELECT DISTINCT(tbl_products.product_id), tbl_products.product_title,
tbl_brands.brand_name, tbl_reviews.review_date_added,
NOW() AS time_now
FROM tbl_products, tbl_reviews, tbl_brands
WHERE tbl_products.product_id = tbl_reviews.product_id AND
tbl_products.brand_id = tbl_brands.brand_id
ORDER BY tbl_reviews.review_date_added DESC
Для этого необходимо отфильтровать любые повторяющиеся идентификаторы product_id, к сожалению, выбрав tbl_reviews.review_date_added делает каждую запись уникальной, что означает, что DISTINCT больше не будет работать.
Есть ли какой-либо другой способ выполнить этот запрос, чтобы product_id оставался уникальным?
Я сделал GROUP BY, и проблема в том, что я отображаю tbl_reviews.review_date_added на веб-сайте, и он выбирает самую старую дату. Мне нужна самая последняя дата.
С уважением
Комментарии:
1. Что касается использования max (tbl_reviews.review_date_added) или min (tbl_reviews.review_date_added), вы должны выбрать один tbl_reviews.review_date_added для всех tbl_products.product_id (min и max — это только предложения), иначе это не будет работать (как вы уже заметили).
2. Я прочитал это после того, как я это реализовал. Это действительно работает! =)
Ответ №1:
С приведенным описанием немного сложно быть уверенным, но если review_date_added
это единственная проблема, кажется, что вам нужен MAX () этой даты?
Если следующее не помогает, пожалуйста, не могли бы вы привести пример данных, пример выходных данных и описание того, как вы хотите, чтобы выходные данные были созданы?
SELECT
tbl_products.product_id,
tbl_products.product_title,
tbl_brands.brand_name,
MAX(tbl_reviews.review_date_added) AS review_date_added,
NOW() AS time_now
FROM
tbl_products
INNER JOIN
tbl_reviews
ON tbl_products.product_id = tbl_reviews.product_id
INNER JOIN
tbl_brands
ON tbl_products.brand_id = tbl_brands.brand_id
GROUP BY
tbl_products.product_id,
tbl_products.product_title,
tbl_brands.brand_name
ORDER BY
MAX(tbl_reviews.review_date_added) DESC
Ответ №2:
Distinct работает для всей строки. Круглые скобки находятся как раз вокруг поля:
distinct (a), b, c === distinct a, b, c
Простым решением является group by
. Вы можете использовать min
для выбора самой старой даты.
select tbl_products.product_id
, min(tbl_products.product_title)
, min(tbl_brands.brand_name)
, min(tbl_reviews.review_date_added)
, NOW() AS time_now
FROM tbl_products, tbl_reviews, tbl_brands
WHERE tbl_products.product_id = tbl_reviews.product_id AND
tbl_products.brand_id = tbl_brands.brand_id
GROUP BY
tbl_products.product_id
ORDER BY
min(tbl_reviews.review_date_added) DESC
Обратите внимание, что если у продукта может быть несколько брендов, будет выбран самый низкий.
Ответ №3:
Попробуйте это:
SELECT pr.product_id, pr.product_title,
bd.brand_name,
(SELECT MAX(rev.review_date_added) FROM tbl_reviews rev
WHERE pr.product_id = rev.product_id) AS maxdate,
NOW() AS time_now
FROM tbl_products pr INNER JOIN tbl_reviews re
ON pr.product_id = re.product_id
INNER JOIN tbl_brands bd
ON pr.brand_id = bd.brand_id
GROUP BY pr.product_id
ORDER BY re.review_date_added DESC
или (как предложено @Hogan)
SELECT pr.product_id, pr.product_title,
bd.brand_name, md.maxdate
NOW() AS time_now
FROM tbl_products pr INNER JOIN tbl_reviews re
ON pr.product_id = re.product_id
INNER JOIN tbl_brands bd
ON pr.brand_id = bd.brand_id
INNER JOIN (SELECT product_id, MAX(review_date_added) AS maxdate
FROM tbl_reviews rev GROUP BY product_id) md
ON pr.product_id = md.product_id
GROUP BY pr.product_id
ORDER BY re.review_date_added DESC
Комментарии:
1. Быстрее присоединиться к подзапросу с максимальными датами проверки, чем выполнять подзапрос к каждой строке
2. @Hogan: как вы думаете, мой новый запрос правильный? Я действительно не могу это попробовать;)
3. Мне кажется правильным. Я думаю, это будет быстрее, чем принятый ответ. (Также не могу протестировать это прямо сейчас 🙂
Ответ №4:
Я объединил ответ Andomar с некоторыми изменениями, которые вы найдете здесь.
SELECT tbl_products.product_id, tbl_products.product_title,
tbl_products.product_date_added, tbl_brands.brand_name,
MAX(tbl_reviews.review_date_added) AS review_date_added, NOW() AS time_now
FROM tbl_products, tbl_reviews, tbl_brands
WHERE tbl_products.product_id = tbl_reviews.product_id AND
tbl_products.brand_id = tbl_brands.brand_id
GROUP BY tbl_products.product_id
ORDER BY MAX(tbl_reviews.review_date_added) DESC
Работает прекрасно и показывает самую последнюю дату в tbl_reviews.review_date_added.review_date_added.
С уважением