简体   繁体   English

根据行值按行分割数据

[英]split data row wise based on row values

I have a table that stores information in the below format. 我有一个表,以以下格式存储信息。

在此处输入图片说明

id, value , property are the columns. id,value,property是列。 I have a requirement now to sum up data based on property. 我现在有一个要求根据属性汇总数据。

ie for property column F2 and Value, 即对于属性列F2和值,

I need values summed up and displayed as below: 我需要将值汇总并显示如下:

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

Note: I know this is not the way to store data in a table, but table alterations are currently not possible. 注意:我知道这不是在表中存储数据的方法,但是当前无法更改表。

Appreciate if you could give your inputs on this. 感谢您是否可以为此提供意见。

This looks like a really bad design. 这看起来是一个非常糟糕的设计。 It looks like you are using the positions in the table to assign "groupings". 您似乎正在使用表格中的位置来分配“分组”。 Fortunately, you have an id column, so this is possible to do in SQL. 幸运的是,您有一个id列,因此可以在SQL中完成。

Here is the idea: First assign the appropriate F2 property to each row. 这是一个想法:首先为每行分配适当的F2属性。 Then do an aggregation. 然后进行汇总。 This following uses outer apply for the first part and group by for the second: 以下是第一部分使用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;

This doesn't filter out the first group (all 0's). 这不会过滤掉第一个组(全0)。 You can do that with an additional WHERE clause if you like. 如果愿意,可以使用其他WHERE子句来实现。

Here's another solution which uses LEAD in case if you are running SQL Server 2012+ (note my comments). 如果您正在运行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;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM