2015-01-05 13 views
-2

Структура таблицы:SQL-запрос MAX (SUM (..))

Article(
    model int(key), 
    year int(key), 
    author varchar(key), 
    num int) 

Num: количество статей написал в течение года

Найти всех авторов, что каждый из них в течение одного года по крайней мере писал максимальное число статей (по отношению ко всем другим авторам)

Я пробовал:

SELECT author FROM Article, 
(SELECT year,max(sumnum) s FROM 
(SELECT year,author,SUM(num) sumnum FROM Article GROUP BY year,author) 
GROUP BY year) AS B WHERE Article.year=B.year and Article.num=B.s; 

это правильный анс WER? Спасибо.

+1

Нет, это неправильный ответ. В большинстве баз данных это вернет синтаксическую ошибку в предложении 'having'. –

+0

фиксированный это, спасибо. – Signer3

+0

Переключитесь на JOIN. Это имеет больше смысла в РА и будет «ах-ха!». один раз видно. – user2864740

ответ

2

Вы указываете домашнее задание и действительную попытку, какую бы то ни было ошибку.

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

model year author num 
===== ==== ====== === 
1  2013 A  15 
2  2013 C  18 
3  2013 X  17 
4  2014 A  16 
5  2014 B  12 
6  2014 C  16 
7  2014 X  18 
8  2014 Y  18 

Таким образом, ожидаемый результат является самым высоким показателем в 2013 году = 18 и будет возвращать только автор «C». В 2014 году самый высокий отсчет статья 18 и возвратит авторы «X» и «Y»

Во-первых, получить запрос о том, что было максимальное количество статей, написанных ...

select 
     year, 
     max(num) as ArticlesPerYear 
    from 
     Article 
    GROUP BY 
     year 

Это дало бы вы один рекорд в год и максимальное количество опубликованных статей ... так что если у вас были данные за годы 2010-2014, вы бы в MOST получили 5 записей.Теперь это так просто, как присоединение этого к исходной таблице, которая имела согласующий год и статьи

select 
     A2.* 
    from 
     (select 
       year, 
       max(num) as ArticlesPerYear 
      from 
       Article 
      GROUP BY 
       year) PreQuery 
     JOIN Article A2 
      on PreQuery.Year = A2.Year 
      AND PreQuery.ArticlesPerYear = A2.num 
2

Вы могли бы хотеть попробовать самодиагностику JOIN, чтобы получить то, что вы ищете:

SELECT Main.author 
FROM Article AS Main 
INNER JOIN (
    SELECT year 
     ,author 
     ,SUM(num) AS sumnum 
    FROM Article 
    GROUP BY year 
     ,author 
) AS SumMain 
    ON SumMain.year = Main.year 
     AND SumMain.author = Main.author 
GROUP BY Main.author 
HAVING SUM(Main.num) = MAX(SumMain.sumnum) 
; 

Это будет гарантировать (как ANSI) вы получаете MAX из SUM Средних num с и только возвращая результаты за то, что вам нужно. Имейте в виду, что я только JOIN редактировал эти два поля из-за предоставленной информации ... если у вас есть уникальный идентификатор, вы можете указать JOIN, или вам потребуется более конкретная информация, чтобы получить соответствие 1 к 1, соответствующим образом отрегулируйте.

В зависимости от того, что СУБД вы используете, она может быть упрощена один из двух способов:

SELECT author 
FROM (
    SELECT year 
     ,author 
     ,SUM(num) AS sumnum 
    FROM Article 
    GROUP BY year 
     ,author 
    HAVING SUM(num) = MAX(sumnum) 
) AS Main 
; 

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

Если ваша СУБД позволяет выполнять функции OLAP, вы можете сделать что-то вроде этого:

SELECT author 
FROM (
    SELECT year 
     ,author 
     ,SUM(num) AS sumnum 
    FROM Article 
    GROUP BY year 
     ,author 
) AS Main 
QUALIFY (
    ROW_NUMBER() OVER (
     PARTITION BY author 
      ,year 
     ORDER BY sumnum DESC 
    ) = 1 
) 
; 

Какой бы ограничить результирующий набор только самого высокого sumnum, хотя, возможно, потребуется больше параметров для обработки вещей, если вы хотели, чтобы участвовали year (вы - GROUP, и только по этой причине я поднимаю его).

Надеюсь, это поможет!

0

Я предлагаю КТР

WITH maxyear AS 
    (SELECT year, max(num) AS max_articles 
    FROM article 
    GROUP BY year) 
SELECT DISTINCT author 
FROM article a 
JOIN maxyear m 
ON a.year=m.year AND a.num=m.max_articles; 

, и сравнить характеристики по сравнению с перегородкой, которая является еще способ

SELECT DISTINCT author FROM 
    (SELECT author, rank() AS r 
    OVER (PARTITION BY year ORDER BY num DESC) 
    FROM article) AS subq 
WHERE r = 1; 

Я думаю, что некоторые РСУБДЫ позволяют поместить HAVING rank()=1 на вложенном запросе, а затем вам не нужно гнездовые запросы.