TSQL:在不使用内部查询的情况下获得每个组的最小值

时间:2016-10-28 22:12:33

标签: sql-server tsql ssms

很难解释这一点,但我说我有这张桌子

DateTime    ID# Type       Cost
8/1   8pm   1   Activate    2
8/1   8pm   1   Add         15
8/1   10am  1   Add         30
8/1   1pm   1   Use         NULL
8/5   6pm   1   Use         NULL
8/5  11pm   1   Add         14
8/12 9am    1   Use         NULL
8/15 11am   1   Add         100
8/15 1130am 1   Add         10
8/15 5pm    1   Use         NULL
8/1   8pm   2   Activate    2
8/1   8pm   2   Add         15
8/1   10am  2   Add         30
8/1   1pm   2   Use         NULL
8/3   6pm   2   Use         NULL
8/3   12pm  2   Add         14
8/12 9am    2   Use         NULL
8/15 11am   2   Add         90
8/18 5pm    2   Use         NULL

我是由CardNumber做过一个小组

1
2

然后我做了:

SELECT CardNumber
       ,SUM(Case when Type = 'Add' then Cost ELSE 0 END) as totalMoneyAdd
FROM Table 
Group by CardNumber

1   169
2   105

现在我想添加另一个列而不使用内部查询或嵌套查询,这样对于每个ID#它将有一个聚合总和列,其中只会获取每个ID#的初始添加的总和一天。

例如,ID#1在8 / 1,8 / 5,8 / 12和8/15中有效。如果你仔细观察,在8/1,最初的'添加'对于Id#1是15美元,对于8/5初始是14,对于8/12是0,对于8/15是100.对于ID#1,添加所有这些首字母将是129美元。相同的计算将适用于Id#2

总的来说,我想要:

1   169  129
2   115  119

我希望在不使用内部查询或嵌套查询的情况下实现此目的,这意味着只需添加类似

的列
SELECT CardNumber
       ,SUM(Case when Type = 'Add' then Cost ELSE 0 END) as totalMoneyAdd
       --,Add calculations here to calculate this new column
FROM Table 
Group by CardNumber

我正在考虑使用某种分区,但这需要我在from子句中创建嵌套查询或查询。我想知道这是否可以实现。

1 个答案:

答案 0 :(得分:0)

是的,您是对的,您需要使用分区来解决此问题。就内连接或嵌套sql而言,您需要对这些类型的查询使用嵌套查询。 我的anwser不匹配,因为你认为计算中有一些错误。我已经为您创建了两个示例查询。首先是内部查询,第二次没有内部查询,如下所示。我将日期和时间分成两列,因为我没有物理表。请为此进行必要的转换。在第二次查询的情况下,它不会按照您的要求提供结果集,但请检查您是否可以在您的情况下使用它,因为您只需要按ID对其进行分组并将其他列相加以获得所需的结果。

查询1:

select id,sum(cost) totalmoneyadd, sum(totalmoneyinit) totalmoneyinit
from
(
    select 
    id
    ,cost
    , case when rank() over (partition by id,date order by id,date,time) =1 then cost else null end totalmoneyinit 
    from
    (
        select '8/1' date,20 time, 1 id,'Activate' type, 2 cost
        union
        select '8/1',20,   1,'Add', 15
        union
        select '8/1',10, 1,'Add',         30
        union
        select '8/1',13,   1,'Use',       NULL
        union
        select '8/5',18,  1,'Use',         NULL
        union
        select '8/5',23,   1,'Add',         14
        union
        select '8/12', 9,    1,'Use',         NULL
        union
        select '8/15', 11,   1,   'Add',         100
        union
        select '8/15', 11.5, 1,'Add',         10
        union
        select '8/15',17,    1 ,  'Use',  NULL
        union
        select '8/1',20,   2,'Activate',    2
        union
        select '8/1',20,   2 ,'Add',         15
        union
        select '8/1',   10,  2,'Add',         30
        union
        select '8/1',13,   2,'Use',         NULL
        union
        select '8/3',18,   2,'Use',         NULL
        union
        select '8/3',   12,  2   ,'Add',         14
        union
        select '8/12', 9,    2   ,'Use',         NULL
        union
        select '8/15', 11,   2   ,'Add',         90
        union
        select '8/18', 17,    2   ,'Use',         NULL
    )A
    where type='Add'
) B
group by id

查询2:

select 
case when rank() over (partition by id,date order by id,date,time) =1 then id else null end id
,case when rank() over (partition by id,date order by id,date,time) =1 then sum(cost) over (partition by id,date order by id,date,time desc) else null end totalmoneyadd 
, case when rank() over (partition by id,date order by id,date,time) =1 then cost else null end totalmoneyinit 
from
(
    select '8/1' date,20 time, 1 id,'Activate' type, 2 cost
    union
    select '8/1',20,   1,'Add', 15
    union
    select '8/1',10, 1,'Add',         30
    union
    select '8/1',13,   1,'Use',       NULL
    union
    select '8/5',18,  1,'Use',         NULL
    union
    select '8/5',23,   1,'Add',         14
    union
    select '8/12', 9,    1,'Use',         NULL
    union
    select '8/15', 11,   1,   'Add',         100
    union
    select '8/15', 11.5, 1,'Add',         10
    union
    select '8/15',17,    1 ,  'Use',  NULL
    union
    select '8/1',20,   2,'Activate',    2
    union
    select '8/1',20,   2 ,'Add',         15
    union
    select '8/1',   10,  2,'Add',         30
    union
    select '8/1',13,   2,'Use',         NULL
    union
    select '8/3',18,   2,'Use',         NULL
    union
    select '8/3',   12,  2   ,'Add',         14
    union
    select '8/12', 9,    2   ,'Use',         NULL
    union
    select '8/15', 11,   2   ,'Add',         90
    union
    select '8/18', 17,    2   ,'Use',         NULL
)A
where type='Add'