根据行值

时间:2016-11-07 18:29:46

标签: sql sql-server tsql

我有一个表格,以下列格式存储信息。

enter image description here

id,value,property是列。我现在要求根据财产总结数据。

即属性列F2和Value,

我需要总结并显示如下的值:

Type | Sum
Cars   |  1892+702+515 
Bikes  | 1393 +0 + 474.6

注意:我知道这不是在表中存储数据的方法,但目前无法进行表格更改。

感谢你能否就此提出意见。

2 个答案:

答案 0 :(得分:1)

这看起来非常糟糕。看起来您正在使用表中的位置来分配“分组”。幸运的是,您有一个id列,因此可以在SQL中执行此操作。

这是一个想法:首先为每一行分配适当的F2属性。然后进行聚合。以下内容使用outer apply作为第一部分,group by作为第二部分:

select t2.value,
       sum(case when isnumeric(t.value) = 1 then cast(t.value as decimal(10, 2))
           end) as thesum
from t outer apply
     (select top 1 t2.*
      from t t2
      where t2.id <= t.id and t2.property = 'F2'
      order by t2.id desc
     ) t2
group by t2.value;

这不会过滤掉第一组(全0)。如果您愿意,可以使用额外的WHERE子句来执行此操作。

答案 1 :(得分:1)

如果您正在运行SQL Server 2012+,请使用LEAD的另一种解决方案(请注意我的评论)。

-- Sample data
DECLARE @yourtable 
TABLE 
(
  id       int identity primary key, -- emulate an index on ID 
  value    varchar(100), 
  property varchar(5)
);

INSERT @yourtable (value, property) VALUES 
('0',     'F2'),
('0',     'V1'),
('0',     'V2'),
('0',     'V3'),
('Cars',  'F2'),
('1892',  'V1'),
('702',   'V2'),
('515',   'V3'),
('Bikes', 'F2'),
('1393',  'V1'),
('0',     'V2'),
('474.6', 'V2');

-- Solution
WITH startPoints AS
(
  SELECT *, rn = ROW_NUMBER() OVER (ORDER BY id)
  FROM @yourtable 
),
groups AS
(
  SELECT value, rn, ttl = 
    ISNULL(LEAD(id,1) OVER (ORDER BY id), (SELECT COUNT(*) FROM @yourtable)+1) - (rn+1)
  FROM startPoints
  WHERE property = 'F2' AND value LIKE ('%[^0-9.]%')
)
SELECT
  value, 
  SUM = 
  (
    SELECT SUM(CAST(value AS decimal(10,2)))
    FROM startPoints s
    WHERE s.rn BETWEEN g.rn+1 AND g.rn+ttl
  )
FROM groups g;