将多行的单元格连接成一行
Posted
技术标签:
【中文标题】将多行的单元格连接成一行【英文标题】:Concat cells of multiple rows into one row 【发布时间】:2018-03-06 12:21:09 【问题描述】:我对我的 SQL Server 表有一个非常奇怪的要求,我不确定它是否无法解决。
我有一个客户端网格/表格,它通过给定的 T-SQL 查询/存储过程显示数据。我正在查看的 SQL Server 数据库中的表是带有时间戳的数字数据 - 如下所示:
| DateTime(Key) | Value |
+------------------------+--------+
| 2010-07-27 17:00:00.00 | 1.337 |
| 2010-07-27 18:00:00.00 | 2.453 |
| 2010-07-27 19:00:00.00 | 3.2342 |
现在的要求是在一行中显示更多的“值”列,如下所示:
| DateTime(Key) | Value | Value | Value |
+------------------------+--------+--------+--------+
| 2010-07-27 17:00:00.00 | 1.337 | 2.453 | 3.2342 |
| 2010-07-27 20:00:00.00 | 4.432 | 5.3422 | 6.9484 |
(注意:连续的第一个数字只是为了便于阅读)
现在我想创建一个视图/存储过程,它允许我提供我想要的列的倍数和数量。
我不知道如何解决这个问题。因为您必须查看接下来的 x 行并将它们删除并将它们应用于第一行。
【问题讨论】:
(1) 用您正在使用的数据库标记您的问题。 (2) 你是什么意思“允许我提供我想要的列的倍数和数量。”? 这确实很奇怪,我假设您在一行显示从 17:00 到 19:00 的任何内容,然后跳到 20:00 到 22:00 等。我不知道你为什么想这样做,但据我所知,这一切都可以通过GROUP BY
语句和一些CASE
语句来实现。如果您提供一些测试数据,那么我确定有人可以提供解决方案吗?
实际上,重新阅读您的问题,您希望以这种方式旋转可变数量的行。这几乎肯定必须是动态的,这意味着存储过程可能是最好的解决方案。您可以查看动态 PIVOT
或使用 LEAD
做一些巧妙的事情(也可以动态构造查询)。
@GordonLinoff (1) 完成 (2) 网格实际上接受了任何通用查询,所以我用我解释得很差的知识解释了它。对于上面的示例,我应该只要求“计数”。所以在这种情况下,列 'Value' 3 次。
@woodyplz,试试我的答案。
【参考方案1】:
试试这个:
DECLARE @Tab TABLE(DateTime DateTime, Value NUMERIC(8,5))
INSERT INTO @Tab VALUES('2010-07-27 17:00:00.00',1.337)
INSERT INTO @Tab VALUES('2010-07-27 18:00:00.00',2.453)
INSERT INTO @Tab VALUES('2010-07-27 19:00:00.00',3.2342)
INSERT INTO @Tab VALUES('2010-07-27 20:00:00.00',4.432)
INSERT INTO @Tab VALUES('2010-07-27 21:00:00.00',5.3422)
INSERT INTO @Tab VALUES('2010-07-27 22:00:00.00',6.9484)
SELECT MIN(D.DateTime)DateTime
,MIN(CASE WHEN D.RN=1 THEN D.Value END)Value1
,MIN(CASE WHEN D.RN=2 THEN D.Value END)Value2
,MIN(CASE WHEN D.RN=3 THEN D.Value END)Value3
FROM(
SELECT *
,(CAST(Value AS INT)-1)/3 Val
,ROW_NUMBER() OVER(PARTITION BY (CAST(Value AS INT)-1)/3 ORDER BY DateTime)RN
FROM @Tab
)D
GROUP BY val
结果:
DateTime Value1 Value2 Value3
2010-07-27 17:00:00.000 1.33700 2.45300 3.23420
2010-07-27 20:00:00.000 4.43200 5.34220 6.94840
【讨论】:
嘿,感谢您的快速回答,我在最后一个小时尝试了自己的 LEAD,这似乎很有希望。我现在就试试你的,看起来真不错! @woodyplz,是的,很高兴听到这个消息。不客气……! 这不是动态的,无法处理 x 行。使用动态数据透视脚本。 我想我知道你在做什么。使用 '(CAST(Value AS INT)-1)/3 ',您正在划分 '.'(dot) 之前的值并使用它来标识要分组的行号。我只是使用连续的第一个数字来帮助人们理解我的例子。可悲的是,它只是引起了混乱。 :(【参考方案2】:我找到了一个尚未完全动态的答案,但它解决了基本要求。我稍后会发布完全动态的存储过程。
DECLARE @Count int;
SET @Count = 3;
SELECT TimeUtc, V1, V2, V3 FROM (
SELECT
TimeUtc,
Value as V1,
LEAD(Value, 1, null) over (ORDER BY TimeUtc) AS V2,
LEAD(Value, 2, null) over (ORDER BY TimeUtc) AS V3,
(ROW_NUMBER() OVER (ORDER BY TimeUtc) - 1) % @Count AS RN
FROM MeasurementData
WHERE
) as tbl where RN = 0;
如果我不需要外部选择就好了,但我没有找到解决办法。
【讨论】:
以上是关于将多行的单元格连接成一行的主要内容,如果未能解决你的问题,请参考以下文章
Excel多行内容,合并单元格之后就只显示第一行内容,如何显示其他行?