Подтвердить что ты не робот

Запуск подсчета для каждых 2 рядов

Я пытаюсь подсчитать количество запусков для каждых 2 строк, как показано ниже,

CREATE TABLE sales
(
     EmpId INT, 
     Yr INT, 
     Sales DECIMAL(8,2)
)

INSERT INTO sales (EmpId, Yr, Sales)
VALUES (1, 2005, 12000), (1, 2006, 18000), (1, 2007, 25000),
       (1, 2008, 25000), (1, 2009, 25000),
       (2, 2005, 15000), (2, 2006, 6000), (2, 2007, 6000)

SELECT 
    EmpId, Yr, sales, 
    SUM(Sales) OVER (PARTITION BY empid ORDER BY empid ROWS BETWEEN 2 PRECEDING AND CURRENT ROW ) AS TotalSales2
FROM 
    sales

Вывод:

EmpId   Yr      sales   TotalSales2
-----------------------------------
  1     2005    12000      12000
  1     2006    18000      30000
  1     2007    25000      55000
  1     2008    25000      68000
  1     2009    25000      75000
  2     2005    15000      15000
  2     2006     6000      21000
  2     2007     6000      27000

Но ожидаемый результат:

EmpId   Yr     Sales    TotalSales2
-----------------------------------
  1     2005    12000   12000
  1     2006    18000   30000
  1     2007    25000   25000   
  1     2008    25000   50000
  1     2009    25000   25000   
  2     2005    15000   15000
  2     2006     6000   21000
  2     2007     6000    6000

Что я делаю неправильно в этом запросе?

Примечание: версия SQL Servre - 2012.

4b9b3361

Ответ 1

Выражение:

SUM(Sales) OVER (PARTITION BY empid 
                 ORDER BY empid 
                 ROWS BETWEEN 2 PRECEDING AND CURRENT ROW)

вычисляет сумму, считая текущую строку и две строки, непосредственно предшествующие ей. Таким образом, он фактически вычисляет скользящую сумму, чего вы действительно не хотите.

Я думаю, что вы действительно ищете что-то вроде следующего:

;WITH CTE_Group AS (
    SELECT EmpId, Yr, sales,        
          (ROW_NUMBER() OVER (PARTITION BY empid ORDER BY yr) + 1 ) / 2 AS grp
    FROM sales      
)
SELECT EmpId, Yr, sales,
       SUM(sales) OVER (PARTITION BY empid, grp 
                        ORDER BY yr) AS TotalSales2
FROM CTE_Group

В приведенном выше запросе используется CTE для вычисления поля grp: значение этого поля 1 для первых двух записей раздела empid, 2 для следующих двух записей, и т.д.

Используя grp, мы можем вычислить текущее общее число sales для групп из 2, как и требование OP.

Демо здесь

Edit:

Чтобы компенсировать большую группу записей, попробуйте использовать (кредит указывается @Max Szczurek для указания этого):

(ROW_NUMBER() OVER (PARTITION BY empid ORDER BY yr) - 1 ) / n AS grp

где n - количество записей, содержащихся в каждой группе.

Ответ 2

SELECT EmpId, Yr, Sales, 
    CASE WHEN ROW_NUMBER() OVER (PARTITION BY EmpId ORDER BY yr) % 2 = 0 
    THEN sales + lag(sales, 1, 0) OVER (PARTITION BY empid ORDER BY yr) 
    ELSE sales 
    END AS TotalSales2
FROM sales

Отмена возвращает значение предыдущей строки - когда row_number() равно, добавьте текущее значение строки в предыдущую строку - иначе просто покажите продажи текущей строки. Разделение каждого по EmpId, упорядочение каждого по yr - выход соответствует ожидаемому.

Кроме того, большое спасибо за добавление данных DDL/sample.

Ответ 3

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

DECLARE @sales TABLE(EmpId INT, Yr INT, Sales DECIMAL(8,2))

INSERT INTO @sales ( EmpId, Yr, Sales )
VALUES  (1, 2005, 12000),
      (1, 2006, 18000),
      (1, 2007, 25000),
      (1, 2008, 25000),
      (1, 2009, 25000),
      (2, 2005, 15000),
      (2, 2006, 6000),
      (2, 2007, 6000)
;WITH SAMPLE_DATA
AS
(
SELECT ROW_NUMBER()over(partition by empid order by (select 100))SNO,* FROM     @Sales
)
SELECT EmpId,Yr,Sales
    ,CASE WHEN (SNO%2=0)
     THEN SALES+
    (
        SELECT Sales FROM SAMPLE_DATA T2 WHERE T2.EmpId=T1.EmpId AND     T2.SNO=T1.SNO-1
    )
    ELSE Sales END 
TotalSales2
FROM SAMPLE_DATA T1

OUTPUT

--------------------------------------
--EmpId Yr  Sales   TotalSales2
--------------------------------------
1   2005    12000.00    12000.00
1   2006    18000.00    30000.00
1   2007    25000.00    25000.00
1   2008    25000.00    50000.00
1   2009    25000.00    25000.00
2   2005    15000.00    15000.00
2   2006    6000.00     21000.00
2   2007    6000.00     6000.00
--------------------------------------