如何在不使用数据透视和反透视的情况下在 SQL Server 中水平显示数据?

Posted

技术标签:

【中文标题】如何在不使用数据透视和反透视的情况下在 SQL Server 中水平显示数据?【英文标题】:How to display data horizontally in SQL Server without using pivot and unpivot? 【发布时间】:2017-12-20 12:57:00 【问题描述】:

有没有什么方法可以在不使用pivot和unpivot方法的情况下在sql中显示水平数据?下图是使用 pivot 和 unpivot 的示例,但我想知道还有其他方法吗?

示例

原始数据

+----+-------+-----------------+
| id | Place | Location        |
+----+-------+-----------------+
|  1 |  CP01 | 3.1415,101.7231 |
|  2 |  CP02 | 3.2314,101.3254 |
|  3 |  CP03 | 3.9415,101.0192 |
|  4 |  CP04 | 3.5490,102.0435 |
|  5 |  CP05 | 3.2562,101.2597 |
|  6 |  CP06 | 3.1134,102.5915 |
+----+-------+-----------------+

水平数据

+----------+-----------------+-----------------+-----------------+-----+
| Cols     | 1               | 2               | 3               | ... |
+----------+-----------------+-----------------+-----------------+-----+
| Location | 3.1415,101.7231 | 3.2314,101.3254 | 3.9415,101.0192 | ... |
|    Place | CP01            | CP02            | CP03            | ... |
+----------+-----------------+-----------------+-----------------+-----+

Image for clarification

【问题讨论】:

你为什么不想使用PIVOT PIVOT 不会产生这样的行。这正是您希望数据的样子吗?您必须将两个 PIVOT 合并在一起,或者在您的案例/时间变得非常广泛,可能在交叉连接中生成任意行 ...或者只是在前端正确地进行这种表示转换,而不是试图让 DBMS 生成 2 'rows per row' 之类的... 【参考方案1】:

你可能会寻找这样的东西:

DECLARE @GeoData TABLE (Id INT, Place VARCHAR(10), [Location] VARCHAR(100))

INSERT INTO @GeoData

 SELECT 1,'CP01','3.1415,101.7231' 
 UNION ALL
 SELECT 2,'CP02','3.2314,101.3254'

SELECT  'Location' AS Cols,
        MAX(CASE WHEN t.Id = 1 THEN t.Location END) AS [1],
        MAX(CASE WHEN t.Id = 2 THEN t.Location END) AS [2],
        MAX(CASE WHEN t.Id = 2 THEN t.Location END) AS [3]      
 FROM @GeoData t

 UNION ALL

 SELECT  'Place' AS Cols,
        MAX(CASE WHEN t.Id = 1 THEN t.Place END) AS [1],
        MAX(CASE WHEN t.Id = 2 THEN t.Place END) AS [2],
        MAX(CASE WHEN t.Id = 2 THEN t.Place END) AS [3]     
 FROM @GeoData t

【讨论】:

【参考方案2】:

类似的方式是你可以使用交叉应用和一些条件聚合来实现pivotunpivot方式

SELECT a.Col1, MAX(case when a.ID = 1 then a.Value end) [1],
               MAX(case when a.ID = 2 then a.Value end) [2],
               MAX(case when a.ID = 3 then a.Value end) [3]
FROM table T
CROSS APPLY (VALUES ('Place', T.place, T.ID),
                    ('Location', T.Location, T.ID)
            ) as a(Col1, Value, ID)
group by a.Col1

【讨论】:

我尝试使用这种方法,但结果不是我想要的。数据需要水平显示

以上是关于如何在不使用数据透视和反透视的情况下在 SQL Server 中水平显示数据?的主要内容,如果未能解决你的问题,请参考以下文章

如何在不使用 SQL 中的 PIVOT 函数的情况下进行透视?

如何在不使用数据透视的情况下将行转换或转置为 SQL 中的列?

在没有聚合的情况下在 SQL 中透视表

在 Postgresql 中反透视

在 SQL 中不进行聚合的数据透视

在不知道其中一个外键的情况下删除数据透视表行