Максимум суммы в SQL

У меня есть список магазинов, отделов внутри магазинов и продаж для каждого отдела, например (созданный с использованием max (sales) в подзапросе, но здесь это не так уж важно, я не думаю):

toronto    baskets 500
vancouver  baskets 350
halifax    baskets 100
toronto    noodles 275
vancouver  noodles 390
halifax    noodles 120
halifax    fish    200

Я хотел бы попросить самый продаваемый отдел в каждом магазине. Результат должен выглядеть так:

toronto    baskets 500
vancouver  noodles 275
halifax    fish    200

Когда я использую GROUP BY, он включает все списки из моего подзапроса. Есть ли хороший чистый способ сделать это без временной таблицы?

Какая платформа базы данных? sql сервер? оракул?

TheSoftwareJedi 04.11.2008 03:12

Кто бы мог подумать, что лапша будет такой популярной в Ванкувере, а?

TheSoftwareJedi 04.11.2008 03:14

Это снова «выбрать победителя». stackoverflow.com/questions/246870/simple-sql-query

Amy B 04.11.2008 15:48

Этот вопрос следует заблокировать.

sam yi 01.02.2012 02:37
ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
8
4
29 817
7

Ответы 7

Это работает в Oracle, другие реализации могут иметь другой синтаксис для аналитических функций (или полностью их не иметь):

select store
     , max(department) keep(dense_rank last order by sales)
     , max(sales)
  from (
        ...query that generates your results...
       )
 group by store

Да, я собирался это предложить, но я думаю, что он работает на SQL Server (как сказал бы любой, кто использует oracle ...)

TheSoftwareJedi 04.11.2008 03:21

Это будет работать в SQL Server с 2005 года:

with data as
(select store, department, sales
from <your query>),
 maxsales as
(select store,  sales = max(sales)
from data
group by store)
select store, (select top 1 department from data where store = t.store and sales = t.sales order by [your criteria for ties]), sales
from maxsales m

Я предполагаю, что вы хотите отображать только 1 отдел в случае наличия связей, следовательно, 1 верхний и [ваши критерии связей], чтобы различать их.

Может, это сработает. Хотя не пробовал, может быть лучшее решение ...

select yourTable.store, dept, sales
from yourTable
join (
  select store, max(sales) as maxSales from yourTable group by store
) tempTable on tempTable.store = yourTable.store 
           and tempTable.maxSales = yourTable.sales

К сожалению, я опубликовал аналогичное решение на несколько минут позже. Этот запрос не будет выполняться так, как было опубликовано. Группа) до должна исчезнуть, значение max (sales) в таблице tempTable не имеет имени, а в столбцах в списке выбора необходимо указать их источник. Не хочу быть аналом, но если кто-то появится позже, я хотел, чтобы это было ясно.

Pete 04.11.2008 03:53

Это работает в Sql Server (2000 и выше наверняка)

SELECT a.Store, a.Department, a.Sales
FROM temp a
INNER JOIN 
(SELECT store, max(sales) as sales
FROM temp
GROUP BY Store) b
ON a.Store = b.Store AND a.Sales = b.Sales;

Это будет работать в SQL Server без временных таблиц:

SELECT Store, Department, Sales FROM
(SELECT Store, Department, Sales,
DENSE_RANK()  OVER (PARTITION BY Store
ORDER BY Sales DESC) AS Dense_Rank
FROM Sales) A WHERE Dense_Rank = 1

ГДЕ "Продажи" = ваш исходный запрос

Это решение только для SQL 2005 и выше.

Sean Carpenter 04.11.2008 05:50

Это будет работать

Select Store, Department, Sales
From yourTable A
Where Sales = (Select Max(Sales)
               From YourTable
               Where Store = A.Store)

Мои 2 решения для SQL 2005 приведены ниже. Другие, которые я вижу до сих пор, могут не возвращать правильные данные, если два показателя продаж совпадают. Однако это зависит от ваших потребностей.

Первый использует функцию Row_Number (), все строки ранжируются от самых низких до самых высоких продаж (затем некоторые правила разрешения ничьей). Затем для каждого магазина выбирается наивысший рейтинг.

Вы можете попробовать добавить предложение Partion By к функции Row_Number (см. BOL) и / или исследовать, используя внутреннее соединение вместо предложения in.

Второй, заимствуя идею под ключ, снова ранжирует их, но разбивает по магазинам, так что мы можем выбрать первый ранжированный. Dense_Rank, возможно, даст двум идентичным строкам одинаковый ранг, поэтому, если магазин и отдел не уникальны, он может вернуть две строки. С Row_number номер уникален в разделе.

Следует помнить о том, что это может быть медленным, но будет быстрее для большинства наборов данных, чем подзапрос в одном из других решений. В этом решении запрос должен выполняться один раз для каждой строки (включая сортировку и т. д.), Что может привести к множеству запросов.

Другие запросы выбирают максимальные продажи для каждого магазина и возвращают данные таким образом, возвращают повторяющиеся строки для магазина, если у двух отделов одинаковые продажи. Последний запрос показывает это.

DECLARE @tbl as TABLE (store varchar(20), department varchar(20), sales int)

INSERT INTO @tbl VALUES ('Toronto', 'Baskets', 500)
INSERT INTO @tbl VALUES ('Toronto', 'Noodles', 500)
INSERT INTO @tbl VALUES ('Toronto', 'Fish', 300)
INSERT INTO @tbl VALUES ('Halifax', 'Fish', 300)
INSERT INTO @tbl VALUES ('Halifax', 'Baskets', 200)

-- Expect Toronto/Noodles/500 and Halifax/Fish/300

;WITH ranked AS -- Rank the rows by sales from 1 to x
(
    SELECT 
        ROW_NUMBER() OVER (ORDER BY sales, store, department) as 'rank', 
        store, department, sales
    FROM @tbl
)

SELECT store, department, sales
FROM ranked
WHERE rank in (
    SELECT max(rank) -- chose the highest ranked per store
    FROM ranked
    GROUP BY store
)

-- Another way
SELECT store, department, sales
FROM (
    SELECT 
        DENSE_RANK() OVER (PARTITION BY store ORDER BY sales desc, 
store desc, department desc) as 'rank',
        store, department, sales
    FROM @tbl
) tbl
WHERE rank = 1


-- This will bring back 2 rows for Toronto
select tbl.store, department, sales
from @tbl tbl
    join (
        select store, max(sales) as maxSales from @tbl group by store
    ) tempTable on tempTable.store = tbl.store 
           and tempTable.maxSales = tbl.sales

Другие вопросы по теме