2016-06-21 6 views
3

У меня есть таблица, которая имеет три поля, как это:Получить записи с максимальным значением суммы сгруппированных SQL результаты

PK  account  value 
----------------------- 
1  40010101 130 
1  40010101 500 
1  40010569 590 
2  40010569 300 
2  40010101 200 

Я хочу, чтобы выбрать запись, которая имеет наибольшее значение суммы стоимости для каждого ПК, сгруппированные по ПК и счета, поэтому мой результат должен быть таким:

PK  account  value 
----------------------- 
1  40010101 630 
2  40010569 300 

Я попытался это решение:

SELECT 
pn.* 
FROM 
(select PK, account, sum(value) as value 
from table 
group by PK, account) pn 
INNER JOIN 
(select PK, MAX(value) AS maxvalue 
from (select PK, account, sum(value) as value 
     from table 
     group by PK, account) pn 
group by PK) maxsum 
ON pn.PK= maxsum.PK 
AND pn.value = maxsum.maxvalue 

Это работает, но я прошу вас более быстрое решение. Я мог бы записать тысячи записей. Я не могу использовать хранимую процедуру. Использование SQL-сервера.

+1

Вы используете MySQL или SQL Server? Можете ли вы правильно пометить? –

+0

@Kason Вы приняли его вопрос. – Blank

+0

Если вы предоставите ссылку sqlfiddle.com для этого типа вопросов, это поможет нам решить быстрее и точнее. –

ответ

2

В SQL Server

SELECT PK, 
     account, 
     sum_value AS [value] 
FROM (
    SELECT PK, 
      account, 
      SUM([value]) as sum_value, 
      ROW_NUMBER() OVER (PARTITION BY PK ORDER BY SUM([value]) DESC) as rn 
    FROM [table] 
    GROUP BY account, PK 
) as p 
WHERE rn = 1 

Выход:

PK account  value 
1 40010101 630 
2 40010569 300 
+0

thankssss! Это то, что я ищу –

+0

Мое удовольствие! :) – gofr1

1

Один из способов добиться того, что вы хотите с серией объединений:

SELECT t1.PK, t1.account, t1.value 
FROM 
(
    SELECT PK, account, SUM(value) AS value 
    FROM yourTable 
    GROUP BY PK, account 
) t1 
INNER JOIN 
(
    SELECT t.PK, MAX(t.value) AS value 
    FROM 
    (
     SELECT PK, account, SUM(value) AS value 
     FROM yourTable 
     GROUP BY PK, account 
    ) t 
    GROUP BY t.PK 
) t2 
    ON t1.PK = t2.PK AND t1.value = t2.value 

Нажмите на ссылку ниже для запущенной демки:

SQLFiddle

+1

Использовать Макс без группы? – Kason

+0

@TimBiegeleisen Теперь верно, но это похоже на решение с указанным вопросом. :-( – Blank

+0

MySQL не имеет аналитических функций, этот подход может быть не так уж плох в этом случае. –

0
SELECT C.* FROM 
(
    SELECT PK,account,SUM(VALUE) AS VALUE 
    FROM TABLE1 
    GROUP BY PK,account 
) AS C INNER JOIN 
(
    SELECT A.PK, MAX(SUMVALUE) AS MAXVALUE 
    FROM TABLE1 AS A INNER JOIN 
    (
     SELECT PK,account,SUM(VALUE) AS SUMVALUE 
     FROM TABLE1 
     GROUP BY PK,account 

    ) AS B 
    ON A.PK = B.PK 
    AND A.account = B.account 
    GROUP BY A.PK 
) AS D 
ON C.PK =D.PK 
AND C.VALUE = D.MAXVALUE 
0

Они являются по существу эквивалентными (на самом деле это то, как некоторые базы данных реализуют DISTINCT под капотом).

Если один из них быстрее, это будет DISTINCT. Это связано с тем, что, хотя оба они одинаковы, оптимизатор запросов должен уловить тот факт, что ваша GROUP BY не использует преимущества каких-либо членов группы, просто их ключи. DISTINCT делает это явным, так что вы можете уйти с немного более тупым оптимизатором.

Если вы сомневаетесь, тест

0

сделать так, используя подзапрос

select id,account,max(amount) as value 
from 
(
select id,account,sum(value) as amount 
from temp_max 
group by account,id 
order by id 
)t 
group by id 
0

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

select t.*, if(@pk = `PK`, @rowno := @rowno + 1, @rowno := 1) as vrowno, @pk := `PK` as vpk 
from (
    select `PK`, `account`, sum(`value`) as `value` 
    from table1 
    group by `PK`, `account` 
    order by `PK`, `value` desc) t 
cross join (select @pk := '', @rowno := 0) v 
having vrowno = 1 

SQLFiddle DEMO HERE

Надеется, что это поможет. :-)

1

Вы можете попробовать ниже запрос будет работать

SELECT pk, 
     SUBSTRING_INDEX(GROUP_CONCAT(account ORDER BY val DESC),',',1) AS account, 
     MAX(val) AS val 
FROM (
    SELECT pk, 
      account, 
      SUM(`value`) AS val 
    FROM test.temp_69 
    GROUP BY pk,account 
    ORDER BY pk 
    ) AS t 
GROUP BY pk; 
+0

Я выполнил над запросом его рабочий тон –

0

У меня есть еще один ответ на подзапрос и предел 1 в MySQL:

select PK, account, 
    (select Sum(value) FROM yourTable t2 where t1.PK=t2.PK group by PK,account order by Sum(value) desc limit 1) max_sum 
from yourTable t1 
where (PK, account)= 
    (select PK,account FROM yourTable t2 where t1.PK=t2.PK group by PK,account order by Sum(value) desc limit 1) 
group by PK, account; 

Я не знаю его производительность лучше или нет. Пожалуйста, проверьте его эффективность и сообщите нам.

Я также предоставил ссылку Sqlfiddle.

Смежные вопросы