SQL Server多个分组

时间:2015-06-08 14:19:12

标签: sql sql-server grouping window-functions

我对看似简单的问题感到困惑。 我们有以下表格。

ID---   ---Income---       ---Years Offset---       ---Income By Offset---
 1          1000                 1                         NULL
 2           500                 1                         NULL
 3           400                 1                         NULL
 4            0                  1                         NULL
 5          2000                 2                         NULL
 6            0                  2                         NULL              
 7           400                 2                         NULL

我想知道如何做的是将所有收入列加上“年度偏移列”并放在“按收入列收入”列的第一行。如果“按收入计算的收入”列在第1行中的值为1900,在第5行中的值为2400,其余部分的行未被触及,那将是多么令人敬畏。

我知道这听起来像一个简单的问题。但是我已经尝试了Window函数,Row_number(),SELF连接表,并且每个表都解决了,但是我很难将它们放在一起。

提前致谢, 乔治

3 个答案:

答案 0 :(得分:2)

我的桌子版本

DECLARE @yourTable TABLE (ID INT,Income INT,[Years Offset] INT,[Income By Offset] INT NULL);

INSERT INTO @yourTable
VALUES  (1,1000,1,NULL),
        (2,500,1,NULL),
        (3,400,1,NULL),
        (4,0,1,NULL),
        (5,2000,2,NULL),
        (6,0,2,NULL),
        (7,400,2,NULL);

实际查询

SELECT  ID,
        Income,
        [Years Offset],
        CASE
            WHEN ID = MIN(ID) OVER (PARTITION BY [Years Offset])
                THEN SUM(Income) OVER (PARTITION BY [Years Offset])
            ELSE [Income By Offset]
        END AS [Income By Offset]
FROM @yourTable

结果

ID          Income      Years Offset Income By Offset
----------- ----------- ------------ ----------------
1           1000        1            1900
2           500         1            NULL
3           400         1            NULL
4           0           1            NULL
5           2000        2            2400
6           0           2            NULL
7           400         2            NULL

答案 1 :(得分:0)

这应返回所需的结果集:

  SELECT ID, Income, [Years Offset],
         CASE WHEN ROW_NUMBER() OVER (PARTITION By [Years Offset] 
                                      ORDER BY ID) = 1
            THEN SUM(Income) OVER (PARTITION BY [Years Offset])
              ELSE NULL
         END AS [Income By Offset]
    FROM mytable

SUM的窗口版计算每Income [Years Offset]ROW_NUMBER()仅用于为每个[Years Offset]组的第一行返回此值。

Demo here

答案 2 :(得分:-1)

怎么样:

SQL Fiddle

MS SQL Server 2014架构设置

CREATE TABLE Income
(
  ID INT PRIMARY KEY,
  Income INT NOT NULL,
  YearsOffset Int NOT NULL,
  IncomeByOffset INT NULL
 )

 INSERT INTO Income (ID, Income, YearsOffset)
 VALUES (1,1000,1),
        (2,500,1),
        (3,400,1),
        (4,0,1),
        (5, 2000, 2),
        (6,0,2),
        (7,400,2)

查询1

UPDATE Income
  SET IncomeByOffset = I.IncomeByOffset
From 
(
  SELECT YearsOffset, SUM(Income) As IncomeByOffset, Min(ID) As MinId
  FROM Income
  GROUP BY YearsOffset
 ) I
 WHERE Income.YearsOffset = I.YearsOffset
   AND Income.Id = I.MinId

<强> Results 查询2

SELECT *
FROM Income;

<强> Results

| ID | Income | YearsOffset | IncomeByOffset |
|----|--------|-------------|----------------|
|  1 |   1000 |           1 |           1900 |
|  2 |    500 |           1 |         (null) |
|  3 |    400 |           1 |         (null) |
|  4 |      0 |           1 |         (null) |
|  5 |   2000 |           2 |           2400 |
|  6 |      0 |           2 |         (null) |
|  7 |    400 |           2 |         (null) |