Использование оконной функции для получения максимального значения по нескольким записям - SQL

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

Вот мой код:

SELECT     rcl.CaseCaseId AS CaseId, cc.Label AS CaseName, rpt.RptDateCum, cp.Label, rpt.CorpProductId, corp.Label AS Scenario, proj.Label AS Project, 
                      ProjectScenario.ReportDate
into #CumTemp
FROM         PhdRpt.ReportCaseList_542 AS rcl INNER JOIN
                      CaseScenario AS cs ON rcl.CaseCaseId = cs.CaseCaseId INNER JOIN
                      CorpScenario AS corp ON cs.CorpScenarioId = corp.CorpScenarioId INNER JOIN
                      CaseCases AS cc ON cs.CaseCaseId = cc.CaseCaseId INNER JOIN
                      PhdRpt.RptProductTech_542 AS rpt ON rcl.ReportId = rpt.ReportID AND rcl.ReportRunCaseId = rpt.RptCaseId INNER JOIN
                      CorpProduct AS cp ON rpt.CorpProductId = cp.CorpProductId INNER JOIN
                      ProjProject AS proj ON cs.ProjProjectId = proj.ProjProjectId INNER JOIN
                      ProjectScenario ON cs.ProjProjectId = ProjectScenario.ProjProjectId AND cs.CorpScenarioId = ProjectScenario.CorpScenarioId AND 
                      corp.CorpScenarioId = ProjectScenario.CorpScenarioId AND proj.ProjProjectId = ProjectScenario.ProjProjectId AND 
                      proj.ProjProjectId = ProjectScenario.ProjProjectId
WHERE     (cs.CorpScenarioId = 1) AND (cs.Deleted = 0)
ORDER BY CaseId


Select  ROW_NUMBER() OVER(order by caseid) as Row, CaseId, Scenario,Project, ReportDate, ltrim(str(sum(Gas))) as Gas, ltrim(str(SUM(Oil))) as Oil, ltrim(str(SUM(Water))) as Water
,MAX(oil) over (partition by Project) as oilmax, MAX(gas) over (partition by Project) as gasmax, MAX(water) over (partition by Project) as watermax
from #CumTemp
pivot (max (RptDateCum) for Label in ([Gas], [Oil], [Water]))as x
group by CaseId, Scenario,Project, ReportDate, Oil
order by Row 
drop table #CumTemp

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

Мой желаемый результат будет выглядеть примерно так.

id      oil    gas    water   oilmax    gasmax    watermax   
----------------------------------------------------------
 1       25     12       6      51        98         37
 2       36     98      19      51        98         37
 3       51     19      22      51        98         37
 4       45     77      37      51        98         37
 5       22     64      31      51        98         37

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


person Roland P    schedule 25.10.2013    source источник
comment
вам просто нужно максимальное значение этих столбцов дерева? попробуйте что-нибудь вроде select * from (yourquery), (select max(oil) as oilmax, max(gas), max(water) from (yourquery) ) where someconditions   -  person Jorge Campos    schedule 25.10.2013
comment
Я вздрогнул, когда прочитал предложение ... Мне нужно иметь возможность делать это без представлений из-за динамических имен таблиц.   -  person Tony    schedule 26.10.2013
comment
@RolandP - Вы не упоминаете динамический элемент вашего запроса где-либо еще в вопросе, поэтому примите мой комментарий с долей скептицизма и улыбкой :) Как правило, я избегаю использования динамического SQL (вместо использования view), поэтому сервер может сохранять план выполнения; что может привести к более быстрому выполнению, а также упростить обслуживание кода, потому что все, что вам нужно знать, находится в запросе. Мне интересно узнать, почему и как вы используете имена динамических таблиц.   -  person Tony    schedule 04.11.2013


Ответы (1)


Итак, поскольку ваш запрос очень велик, я покажу, как решить вашу проблему, и вы поместите его в свой запрос. Это мой тестовый пример:

Стол

create table testcase(
    id integer,
    oil integer,
    gas integer,
    water integer
);

Вставки

insert into testcase values ( 1, 25, 12,  6 );
insert into testcase values ( 2, 36, 98, 19);
insert into testcase values ( 3, 51, 19,  22);
insert into testcase values ( 4, 45, 77,  37);
insert into testcase values ( 5, 22, 64,  31);

Sql

select * 
  from testcase as test,
       (select max(oil) maxoil, 
               max(gas) maxgas, 
               max(water) maxwater 
          from testcase) as maxes 
 order by test.id

Это должно дать вам ваши данные так, как вы хотите. Посмотрите на скрипку http://sqlfiddle.com/#!3/be2b7/3/0 < / а>

person Jorge Campos    schedule 25.10.2013
comment
Вложенный оператор выбора находится до или после поворота? Я не могу заставить его работать в любом случае. Значения нефти, газа и воды изначально взяты из одного столбца. - person Roland P; 26.10.2013
comment
Я получаю следующую ошибку Msg 116, Level 16, State 1, Line 14 Only one expression can be specified in the select list when the subquery is not introduced with EXISTS. - person Roland P; 26.10.2013
comment
Я, наконец, смог решить эту проблему, сохранив сводную таблицу в глобальной временной таблице, а затем применив вашу технику. Спасибо @Jorge Campos - person Roland P; 28.10.2013