#php #mysql #opencart
Вопрос:
Моя структура базы данных содержит столбцы: id, name, value, dealer
. Я хочу получить строку с наименьшим value
значением для каждого dealer
. Я пытался все испортить , MIN()
и GROUP BY
все равно — никакого решения.
Комментарии:
1. Что именно вы пробовали? Опубликовав свой код, вы могли бы лучше показать, что приложили некоторые усилия для решения проблемы самостоятельно, и, возможно, кто-то укажет на ошибку, которую вы, возможно, допустили. — В нынешнем состоянии вашего вопроса вы просто просите сделать вашу работу за вас. — На самом деле вы просто объявляете, что не смогли решить проблему, даже не прося о помощи…
2. Мой подход был простым и неправильным: что — то вроде
SELECT MIN(value),dealer FROM table_name GROUP BY dealer;
-я знал, что решение находится где-то в другом месте, поэтому код вводил бы в заблуждение.3. Почему этот код неправильный?
SELECT MIN(value),dealer FROM table_name GROUP BY dealer;
Ответ №1:
Решение 1:
SELECT t1.* FROM your_table t1
JOIN (
SELECT MIN(value) AS min_value, dealer
FROM your_table
GROUP BY dealer
) AS t2 ON t1.dealer = t2.dealer AND t1.value = t2.min_value
Решение 2:
SELECT t1.* FROM your_table t1
LEFT JOIN your_table t2
ON t1.dealer = t2.dealer AND t1.value > t2.value
WHERE t2.value IS NULL
Эта проблема очень известна, поэтому в руководстве Mysql для этого есть специальная страница.
Проверьте это: Строки, содержащие максимум/минимум по группам определенного столбца
Комментарии:
1. Что делать, если дилер А имеет значения 1, 2, 3, а дилер В имеет значения 2, 3, 4? Ваш запрос вернет строки с 1 и 2 для дилера A.
2. @WojtusJ Нет, этого не будет, проверьте запрос еще раз.
3. мой комментарий касался первой редакции вашего ответа без
dealer
каких-либо условий. 🙂 Теперь я вижу, что вы отредактировали его, и это правильно — на самом деле, это то же самое, что и мой ответ. 😉4. @WojtusJ Да, это промах. 🙂
5. Оба работают, но здесь возникает другая проблема — если есть записи с одинаковым значением, они оба возвращаются. Я хочу вернуть только по одному на дилера, поэтому давайте предположим, что они также должны быть сгруппированы по столбцам
time
(чем ниже, тем лучше).
Ответ №2:
select id,name,MIN(value) as pkvalue,dealer from TABLENAME
group by id,name,dealer;
здесь вы группируете все строки по идентификатору,имени,дилеру, а затем получаете минимальное значение в виде значения pk.
Комментарии:
1. Оператору требуется минимальное значение для каждого дилера.
2. Это не то, чего на самом деле хочет OP, если у вас есть две строки с одним и тем же дилером, но разным значением, именем и идентификатором, OP хочет ту, у которой меньшее значение, ваш запрос вернет обе строки.
Ответ №3:
SELECT MIN(value),dealer FROM table_name GROUP BY dealer;
Ответ №4:
Сначала вам нужно определить наименьшее значение для каждого дилера, а затем получить строки, имеющие это значение для конкретного дилера. Я бы сделал это именно так:
SELECT a.*
FROM your_table AS a
JOIN (SELECT dealer,
Min(value) AS m
FROM your_table
GROUP BY dealer) AS b
ON ( a.dealer= b.dealer
AND a.value = b.m )
Ответ №5:
Попробуйте следовать:
SELECT dealer, MIN(value) as "Lowest value"
FROM value
GROUP BY dealer;
Ответ №6:
select id, name, value, dealer from yourtable where dealer
in(select min(dealer) from yourtable group by name, value)
Ответ №7:
Эти ответы, похоже, упускают крайний случай наличия нескольких минимальных значений для дилера и желания вернуть только одну строку.
Если вы хотите, чтобы для каждого дилера требовалось только одно значение, вы можете использовать раздел — группу row_number — таблица по дилерам, а затем упорядочить данные по значению и идентификатору. мы должны исходить из предположения, что вам понадобится строка с наименьшим идентификатором.
SELECT ord_tbl.id,
ord_tbl.name,
ord_tbl.value,
ord_tbl.dealer
FROM (SELECT your_table.*,
ROW_NUMBER() over (PARTITION BY dealer ORDER BY value ASC, ID ASC)
FROM your_table
) AS ord_tbl
WHERE ord_tbl.ROW_NUMBER = 1;
Будьте осторожны, хотя это значение, идентификатор и дилер индексируются. Если нет, это приведет к полному сканированию таблицы и может быть довольно медленным…