2014-01-07 5 views
3

прямо сейчас Я использую таблицу temp в своем sql-запросе, но вместо этого хочу использовать функцию Partition By.Используйте OVER (PARTITION BY) вместо Group By

Мой темп таблица запроса приводится ниже:

drop table #Temp; 

create table #Temp 
(
    NAME varchar(50), 
    EMPID varchar(50), 
    SS MONEY, 
    PP MONEY 
); 

insert into #Temp 
select * From 
( 
    select 
    p1.NAME, 
    p1.EMPID, 
    case when p1.AmtPayer = 'SELF' then sum(p1.Salary) else 0 end as S, 
    case when p1.AmtPayer = 'MANAGER' then sum(p1.Salary) else 0 end as P 
    from Candidate p1 
    group by p1.Name, p1.EMPID, p1.AmtPayer 
) as P; 

select 
t.NAME, 
t.EMPID, 
sum(t.SS) as 'SELF PAID', 
sum(t.PP) as 'PARTY PAID' 
from #Temp t 
group by t.NAME, t.EMPID; 

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

select 
NAME, 
EMPID, 
sum(Salary) over (partition by AmtPayer) as Total 
from dbo.Candidate 

Выход:

 
Vivek 0001 300.00 
Vivek 0001 300.00 
Vivek 0001 6200.00 
Vivek 0001 6200.00 
Vivek 0001 6200.00 

Но мне нужно:

 
Vivek 0001 6200.00 300.00 
+0

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

+0

Если вы хотите, чтобы результат был сгруппирован, вам нужно использовать группу. Вся цель оконных функций не является ** не ** «уменьшать» набор результатов. –

+0

Возможный дубликат [Объединение нескольких результатов в подзапросе в одно значение, разделенное запятыми] (http://stackoverflow.com/questions/111341/combine-multiple-results-in-a-subquery-into-a-ingle- значение, разделенное запятыми) –

ответ

8

Чтобы сделать именно то, что вы хотите, попробуйте следующее:

select 
Name, EmpId, 
sum(case when AmtPayer = 'SELF' then Salary else 0 end) as [Self], 
sum(case when AmtPayer = 'MANAGER' then Salary else 0 end) as [Manager] 
from dbo.Candidate 
group by Name, EmpId; 

Вы можете использовать операторы регистра в совокупности функций, что позволяет сделать много сумасшедшие вещи :)

Однако , как отмечено в моих комментариях к вашему вопросу, это полезно только в том случае, если у вас есть фиксированное количество вариантов AmtPayer, которые вы знаете заранее.

Подробнее: partition byне, чтобы уменьшить набор результатов. Он по-прежнему будет возвращать одну строку за строку, и вы ничего не можете сделать, чтобы изменить это. Если вы хотите уменьшить набор результатов, вместо этого вы используете group by. В сочетании со всеми сложными функциями, которые вы можете выполнять с помощью агрегатных функций, это действительно очень мощный инструмент - и это относится как к partition by, так и к group by. Также обратите внимание, что partition by может быть намного медленнее, чем group by. Фактически, я обнаружил, что использование раздела для получения результата (то есть count over (partition by NULL) или что-то подобное) намного медленнее, чем просто выполнение двух запросов, один для подсчета, а другой для фактических результатов.

Не думайте, что ваш путь лучше, потому что он выглядит умнее - всегда мерите. Профилирование - ваш друг. Такие системы, как SQL Server делают много оптимизаций, которые пытаются все время, чтобы дать вам большую производительность, казалось бы, глупые запросы :)

0

я использовал ниже запроса:

DROP TABLE #Temp 
CREATE TABLE #Temp(
NAME VARCHAR(50), 
EMPID VARCHAR(50), 
SS MONEY, 
PP MONEY 
) 
INSERT INTO #Temp 
Select * From(
SELECT DISTINCT 
    NAME,EMPID, 
    SUM(CASE WHEN AmtPayer='SELF' then Salary ELSE 0 end) OVER (PARTITION BY AmtPayer) AS SS , 
    SUM(CASE WHEN AmtPayer='MANAGER' THEN Salary ELSE 0 end) OVER (PARTITION BY AmtPayer) AS PP 
FROM dbo.Candidate 
)AS P 
SELECT DISTINCT t.NAME ,t.EMPID ,SUM(t.SS) OVER(PARTITION BY t.NAME,t.EMPID) AS 'SELF PAID', 
SUM(t.PP) OVER(PARTITION BY t.NAME,t.EMPID) AS 'PARTY PAID' FROM #Temp t 
--GROUP BY t.NAME ,t.EMPID 
Смежные вопросы