#mysql #sql #max #aggregate #min
#mysql #sql #макс #агрегировать #мин.
Вопрос:
Таблица, содержащая разные статьи. Задача состоит в том, чтобы выбрать артикул с самой высокой и с самой низкой ценой плюс их артикульный номер (первичный ключ)
Это кажется простым MAX
/ MIN
, но на самом деле получается не так хорошо..
SELECT ArtNr, MAX(Price) AS Most_expensive, MIN(Price) AS CHEAPEST FROM article;
Он показывает мне только номер статьи самой дешевой статьи.
Как я могу это исправить?
Большое спасибо!
Комментарии:
1. Пожалуйста, поделитесь таблицей / кодом, очень сложно ответить, не имея ее
2. Что, если есть связи?
Ответ №1:
один из способов:
SELECT ArtNr, MAX(Price), 'Most Expensive'
FROM article
GRoup By ArtNr
union all
SELECT ArtNr, MIN(Price), 'Cheapest'
FROM article
GRoup By ArtNr
Комментарии:
1. Этот запрос, вероятно, сгенерирует синтаксическую ошибку, поскольку
ArtNr
то, что не агрегируется, не является частьюGROUP BY
предложения…
Ответ №2:
В MySQL 8.0 вы можете использовать ROW_NUMBER()
:
SELECT * FROM (
SELECT
ArtNr,
Price,
ROW_NUMBER() OVER(ORDER BY Price) rn_asc,
ROW_NUMBER() OVER(ORDER BY Price DESC) rn_desc
FROM article
) x WHERE rn_asc = 1 OR rn_desc = 1
Подзапрос присваивает ранг каждому товару, упорядоченному по возрастанию или убыванию цены. Внешний запрос фильтрует верхние и нижние цены.
Если вы хотите разрешить привязки сверху и снизу, вы можете использовать RANK()
вместо ROW_NUMBER()
.
В более ранних версиях MySQL вы могли использовать коррелированные подзапросы с NOT EXISTS
условиями, такими:
SELECT ArtNr, Price
FROM article a
WHERE
NOT EXISTS (SELECT 1 FROM article a1 WHERE a1.Price > a.price)
OR NOT EXISTS (SELECT 1 FROM article a2 WHERE a2.Price < a.price)
Комментарии:
1. Добро пожаловать @Henri_99! Если мой ответ правильно ответил на ваш вопрос, пожалуйста, примите его , нажав на зеленый флажок… Спасибо!
Ответ №3:
Использовать В
Живой тест:http://sqlfiddle.com /#!9/686a0f/3
select *
from article a
where a.price in
(
SELECT MAX(Price)
from article
union
SELECT MIN(Price)
from article
)
order by price;
У него просто нет другого столбца, чтобы указать, является ли цена самой высокой или самой низкой. Это все равно сработало бы, хотя, если так случится, что все цены одинаковы, то есть самые дешевые и дорогие одинаковы 🙂
CREATE TABLE article
(`art` varchar(1), `price` int)
;
INSERT INTO article
(`art`, `price`)
VALUES
('A', 1),
('B', 2),
('C', 1),
('D', 3),
('E', 4)
;
Вывод:
| art | price |
|-----|-------|
| A | 1 |
| C | 1 |
| E | 4 |
Ответ №4:
Это может иметь очень хорошую производительность с индексом на price
:
select a.*
from article a
where a.price = (select max(a2.price) from article a2) or
a.price = (select min(a2.price) from article a2);
Это вернет дубликаты. Если вам нужны ровно две строки, независимо от дубликатов:
(select a.*
from article a
order by a.price asc
limit 1
) union all
(select a.*
from article a
order by a.price desc
limit 1
)
Ответ №5:
выберите * из (выберите top 1 ArtNr как ART, Price цена из XCPCONCЗАКАЗ по цене asc) в качестве
объединить все
выберите * from (выберите top 1 ArtNr как ART, Price цена из XCPCONC order по Price desc) как d
Комментарии:
1. MySQL не поддерживает TOP.