Sql 基于行值按行拆分数据
我有一个以以下格式存储信息的表 id、value和property是列。我现在有一个要求,根据财产汇总数据 i、 e表示属性列F2和值 我需要将值汇总并显示如下:Sql 基于行值按行拆分数据,sql,sql-server,tsql,Sql,Sql Server,Tsql,我有一个以以下格式存储信息的表 id、value和property是列。我现在有一个要求,根据财产汇总数据 i、 e表示属性列F2和值 我需要将值汇总并显示如下: Type | Sum Cars | 1892+702+515 Bikes | 1393 +0 + 474.6 注意:我知道这不是在表中存储数据的方法,但表的更改目前是不可能的 如果您能在这方面提供意见,我将不胜感激。这看起来是一个非常糟糕的设计。看起来您正在使用表中的位置来分配分组。幸运的是,您有一个id列,因此在SQL中
Type | Sum
Cars | 1892+702+515
Bikes | 1393 +0 + 474.6
注意:我知道这不是在表中存储数据的方法,但表的更改目前是不可能的
如果您能在这方面提供意见,我将不胜感激。这看起来是一个非常糟糕的设计。看起来您正在使用表中的位置来分配分组。幸运的是,您有一个id列,因此在SQL中可以这样做 想法如下:首先为每一行指定适当的F2属性。然后进行聚合。以下内容对第一部分使用外部应用,对第二部分使用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子句来实现这一点。这看起来是一个非常糟糕的设计。看起来您正在使用表中的位置来分配分组。幸运的是,您有一个id列,因此在SQL中可以这样做 想法如下:首先为每一行指定适当的F2属性。然后进行聚合。以下内容对第一部分使用外部应用,对第二部分使用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子句来实现这一点。如果您运行的是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;
如果您正在运行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;
您如何知道哪些值对应于哪个属性?或者一些查询将数据分成两个表,一个用于自行车,一个用于汽车,这也会有帮助。@vkp,您可以在属性列中看到值F2,与此对应的值是我拆分表的基础。您如何知道哪些值对应于哪个属性?或者一些查询将数据拆分为两个表,一个用于自行车,一个用于汽车,这也会有所帮助。@vkp,您可以在属性列中看到值F2,与此对应的值是我应该拆分表的基础。感谢您的帮助,但我得到的输出类似于此值| thesum 0 | 1867.6 BIKES | NULL Cars | 3109.00抱歉此格式不正确抱歉上面的评论,结果的格式不正确。@MichaelKovattil。您可以设置SQL小提琴吗?我认为这个版本应该可以工作-一旦t1的引用被修复。嘿,它工作得很好。谢谢你。非常感谢。感谢您的帮助,但我得到的输出值如下| thesum 0 | 1867.6 BIKES | NULL Cars | 3109.00抱歉格式不正确抱歉上面的评论,结果格式不正确。@Michaelkovatil。您可以设置SQL小提琴吗?我认为这个版本应该可以工作-一旦t1的引用被修复。嘿,它工作得很好。谢谢你。非常感谢。