Фильтрация таблицы по максимальному количеству вхождений - PullRequest
0 голосов
/ 01 сентября 2018

У меня есть три таблицы столбцов, как показано ниже

| Category  | Author      | Sales     |
+++++++++++++++++++++++++++++++++++++++
| NW        | account-1   | 10        |
| NW        | account-2   | 20        |
| NW        | account-3   | 30        |
| S         | account-4   | 10        |
| S         | account-5   | 50        |
| S         | account-6   | 55        |

Я хотел бы создать другую таблицу с максимальным значением для каждой категории, требуемая таблица должна выглядеть следующим образом.

| Category  | Author      | Sales     |
+++++++++++++++++++++++++++++++++++++++
| NW        | account-3   | 30        |
| S         | account-6   | 55        |

Мой пробный код,

SELECT Category, Author, MAX(Sales)
FROM table
GROUP BY Category, Author

Я не уверен, почему MAX() агрегация не удалась (код выше). Буду признателен, если кто-нибудь объяснит, почему в деталях и предоставит простое и эффективное решение.

Ответы [ 6 ]

0 голосов
/ 09 сентября 2018

вы можете использовать этот запрос для получения ваших данных

;WITH query AS (
    SELECT          
        ROW_NUMBER() OVER (PARTITION BY  Category  ORDER BY Sales DESC) AS [Index],
        Category,
        Sales 
    FROM 
        table
)

SELECT * FROM query WHERE [Index] = 1
0 голосов
/ 08 сентября 2018

Пожалуйста, попробуйте с приведенным ниже утверждением

SELECT * from TableName AS T1 WHERE EXISTS(
  SELECT 1
  FROM TableName AS T2
  WHERE T1.Category = T2.Category
  GROUP BY T2.Category
  HAVING MAX(T2.Sales) = T1.Sales)

Привет

0 голосов
/ 05 сентября 2018

Для ответа на ваш вопрос необходим подзапрос .

Объяснение: Ваше текущее решение не работает, потому что вы не фильтруете исходный запрос по max (Sales) , а просто спрашиваете, что такое максимальные продажи для этой категории? ». Поэтому вам нужен еще один подзапрос, который

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

Следующий код должен работать:

SELECT tbl_sales.Category, tbl_sales.Author, tbl_sales.Sales
FROM tbl_sales
JOIN(
    SELECT Category, MAX(Sales) MaxSales
    FROM tbl_sales
    GROUP BY Category
    ) tbl_maxsales
ON tbl_sales.Sales = tbl_maxsales.MaxSales

Здесь вы можете найти реализацию скрипта SQL .
(Я предполагал, что MySQL 5.6, но это не должно играть большую роль)

Если у вас есть какие-либо вопросы или вам нужны дополнительные рекомендации, пожалуйста, не стесняйтесь, напишите мне сообщение или оставьте комментарий.

0 голосов
/ 05 сентября 2018

Поскольку Group by является групповым значением, когда вы используете GROUP BY Category, Author означает, что вам нужно group by по Category и Author столбцу, так что есть шесть групп.

Запрос

select Category,Author
from t
group by Category,Author

Результаты

| Category |    Author |
|----------|-----------|
|       NW | account-1 |
|       NW | account-2 |
|       NW | account-3 |
|        S | account-4 |
|        S | account-5 |
|        S | account-6 |

но если мы только сделаем group by Category, есть две группы.

Запрос

select Category
from t
group by Category

[Результаты]

| Category |
|----------|
|       NW |
|        S |

Таким образом, вы можете попытаться получить столбец MAX Sales group by Category, затем присоединиться или связаться с Sales и Category

CREATE TABLE T(
    Category varchar(5),
    Author varchar(50),
    Sales int
);


insert into t values ('NW','account-1', 10);
insert into t values ('NW','account-2', 20);
insert into t values ('NW','account-3', 30);
insert into t values ('S','account-4', 10);
insert into t values ('S','account-5', 50);
insert into t values ('S','account-6', 55);

Запрос 1 :

select * from t t1 where exists(
  SELECT 1
  FROM T tt
  WHERE t1.Category = tt.Category
  GROUP BY tt.Category
  HAVING MAX(tt.Sales) = t1.Sales
)

Результаты

| Category |    Author | Sales |
|----------|-----------|-------|
|       NW | account-3 |    30 |
|        S | account-6 |    55 |
0 голосов
/ 01 сентября 2018

Я рекомендую для этого коррелированный подзапрос:

select t.*
from t
where t.sales = (select max(t2.sales) from t t2 where t2.category = t.category);

В частности, почти любая база данных воспользуется индексом (category, sales) - если он доступен - для оптимизации этого запроса.

Проблема с вашим запросом в том, что вы агрегируете по category и author. Вы хотите максимальные продажи в category. А вам нужен автор с максимальными продажами . Это отличается от max(author) или от агрегирования по author.

0 голосов
/ 01 сентября 2018

max () not fail. Вы группируете по категориям, по автору, поэтому ваш запрос возвращает каждую максимальную продажу для каждой комбинации между категорией и автором в вашей таблице. .. если вам нужна строка, относящаяся к категории с максимальными продажами, вы можете использовать внутреннее объединение в подзапросе с максимальным результатом

  select * from my_table m
  inner join (

  select category, max(sales) max_sales
  from  my_table  
  group by category 



  ) t  on t.category  =  m.category and t.max_sales = m.sales 
...