用连续指标计算

时间:2015-07-03 09:26:01

标签: sql sybase sybase-iq

所以这是表格:

Name    Indicator   Amount
Anson       1         3.5
Anson       2         2.6
Anson       3         8.4
Anson       4         3.2
Anson       6         3.7
Ben         1         7
Ben         3         4.7
Ben         4         3.6

如何在指标连续时获得总和金额?这是我想要的结果:

Name    Indicator   Amount
Anson       1,2,3,4  17.7
Anson       6        3.7
Ben         1        7
Ben         3,4      8.3

我试过这个,但它只能结合两个连续的指标。

select name_, indicator, amount, sum_amount,
(CASE WHEN diff = 1 THEN sum_amount ELSE amount END) as final_amount,
(CASE WHEN diff = 1 THEN convert(varchar(10),prev_ind)+',' +convert(varchar(10),indicator) ELSE convert(varchar(10),indicator) END) as indicator

FROM (

select name_, indicator, prev_ind, sum(indicator-prev_ind) as diff, amount,
sum(amount + prev_amount) sum_amount
from (
    select name_, indicator, lag(indicator,1,0) over (order by name_, indicator) prev_ind, amount,
    lag(amount,1,0) over (order by name_) prev_amount
    from tabb
)g
where indicator <> 1
group by name_, indicator, prev_ind, amount

)u

谢谢!

2 个答案:

答案 0 :(得分:0)

您可以使用lag() / lead()函数解决此问题,方法是使用以下方法对IsConsecutive标准和名称列进行分组;

  SELECT P.NAME,
     LISTAGG(P.INDICATOR,',') WITHIN GROUP(ORDER BY P.INDICATOR) INDICATORS,
     SUM (P.AMOUNT) TOTAL
FROM (SELECT Q.AMOUNT,
             Q.NAME,
             Q.INDICATOR,
             CASE WHEN Q.INDICATOR +1 = Q.AFTER OR Q.INDICATOR-1 = Q.BEFORE THEN 'IsConsecutive' ELSE TO_CHAR(Q.INDICATOR) END GRP
        FROM (SELECT T.AMOUNT,
                     T.NAME,
                     T.INDICATOR,
                     LAG (T.INDICATOR) OVER (PARTITION BY T.NAME ORDER BY T.INDICATOR) BEFORE,
                     LEAD (T.INDICATOR)  OVER (PARTITION BY T.NAME ORDER BY T.INDICATOR) AFTER
                FROM YOUR_TABLE T
             )Q
             )P
GROUP BY P.GRP, P.NAME
ORDER BY P.NAME

我为Oracle数据库编写了这个SQL语句。但如果你愿意,你可以轻松转换它。 它提供了所需的输出:

Name     Indicators  Total
Anson    1,2,3,4     17.7
Anson    6           3.7
Ben      1           7
Ben      3,4         8.3

答案 1 :(得分:0)

Sybase支持list功能。我认为获取连续值的最简单方法是从row_number()中减去indicator。连续项的差异是恒定的:

select name, list(indicator), sum(amount)
from (select t.*,
             (row_number() over (partition by name order by indicator) - indicator
             ) grp
      from tabb t
     ) t
group by name, grp;

说实话,我没有看到使用list()确实添加了查询。您还可以输入最小值和最大值:

select name,
       cast(min(indicator) as varchar(255)) + '-' + cast(max(indicator) as varchar(255)) as range,
       sum(amount)
from (select t.*, cast(indicator as varchar(255)) as inds
             (row_number() over (partition by name order by indicator) - indicator
             ) grp
      from tabb t
     ) t
group by name, grp;