如何将Sql列转换为行?
我有一个非常简单的问题,需要在SQL Server 2005中提供非常快速和简单的解决方案。
我有一个带有x列的表。我希望能够从表中选择一行,然后将列转换为行。
TableA Column1, Column2, Column3
ruturn的SQL语句
ResultA Value of Column1 Value of Column2 Value of Column3
@Kevin:我在这个主题上进行过Google搜索,但是在很多示例中,示例过于复杂,我们能否进一步提供帮助?
@Mario:我正在创建的解决方案有10列,存储的值是0到6,我必须计算出多少列的值是3或者更大。因此,我考虑过创建一个查询以将其转换为行,然后在子查询中使用生成的表来计算Column> = 3的行数
解决方案
回答
我们应该看一下UNPIVOT子句。
Update1:GateKiller,奇怪的是,今天早上我读了一篇关于它的文章(关于一些无关的东西),我试图在我再次看到它的地方慢跑,也有一些不错的例子。我敢肯定,它将回到我身边。
更新2:找到它:http://weblogs.sqlteam.com/jeffs/archive/2008/04/23/unpivot.aspx
回答
UNION应该是朋友:
SELECT Column1 FROM table WHERE idColumn = 1 UNION ALL SELECT Column2 FROM table WHERE idColumn = 1 UNION ALL SELECT Column3 FROM table WHERE idColumn = 1
但它也可能成为大型结果集上的敌人。
回答
如果我们有一组固定的列并且知道它们是什么,则基本上可以执行一系列子选择
(从TableA中选择SELECT Column1 AS ResultA)作为R1
并加入子选择。所有这些都在一个查询中。
回答
我不确定为此使用SQL Server语法,但是在MySQL中,我会这样做
SELECT IDColumn, ( IF( Column1 >= 3, 1, 0 ) + IF( Column2 >= 3, 1, 0 ) + IF( Column3 >= 3, 1, 0 ) + ... [snip ] ) AS NumberOfColumnsGreaterThanThree FROM TableA;
编辑:一个非常非常简短的Google搜索告诉我,CASE语句与MySQL中的IF语句一样。我们可能会或者可能不会使用我发现的Google结果
进一步编辑:我还应该指出,这不是问题的答案,而是我们实际问题的替代解决方案。
回答
以前我必须为一个项目做这个。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。我遇到的主要困难之一是向他人解释我想做的事情。我花了很多时间尝试在SQL中执行此操作,但是我发现数据透视功能严重不足。我不记得是什么原因,但是对于大多数应用程序来说,它太简单了,并且在MS SQL 2000中还没有完全实现。我总结了在.NET中编写枢纽函数的方法。我将其张贴在这里,希望有一天能对某人有所帮助。
''' <summary> ''' Pivots a data table from rows to columns ''' </summary> ''' <param name="dtOriginal">The data table to be transformed</param> ''' <param name="strKeyColumn">The name of the column that identifies each row</param> ''' <param name="strNameColumn">The name of the column with the values to be transformed from rows to columns</param> ''' <param name="strValueColumn">The name of the column with the values to pivot into the new columns</param> ''' <returns>The transformed data table</returns> ''' <remarks></remarks> Public Shared Function PivotTable(ByVal dtOriginal As DataTable, ByVal strKeyColumn As String, ByVal strNameColumn As String, ByVal strValueColumn As String) As DataTable Dim dtReturn As DataTable Dim drReturn As DataRow Dim strLastKey As String = String.Empty Dim blnFirstRow As Boolean = True ' copy the original data table and remove the name and value columns dtReturn = dtOriginal.Clone dtReturn.Columns.Remove(strNameColumn) dtReturn.Columns.Remove(strValueColumn) ' create a new row for the new data table drReturn = dtReturn.NewRow ' Fill the new data table with data from the original table For Each drOriginal As DataRow In dtOriginal.Rows ' Determine if a new row needs to be started If drOriginal(strKeyColumn).ToString <> strLastKey Then ' If this is not the first row, the previous row needs to be added to the new data table If Not blnFirstRow Then dtReturn.Rows.Add(drReturn) End If blnFirstRow = False drReturn = dtReturn.NewRow ' Add all non-pivot column values to the new row For Each dcOriginal As DataColumn In dtOriginal.Columns If dcOriginal.ColumnName <> strNameColumn AndAlso dcOriginal.ColumnName <> strValueColumn Then drReturn(dcOriginal.ColumnName.ToLower) = drOriginal(dcOriginal.ColumnName.ToLower) End If Next strLastKey = drOriginal(strKeyColumn).ToString End If ' Add new columns if needed and then assign the pivot values to the proper column If Not dtReturn.Columns.Contains(drOriginal(strNameColumn).ToString) Then dtReturn.Columns.Add(drOriginal(strNameColumn).ToString, drOriginal(strValueColumn).GetType) End If drReturn(drOriginal(strNameColumn).ToString) = drOriginal(strValueColumn) Next ' Add the final row to the new data table dtReturn.Rows.Add(drReturn) ' Return the transformed data table Return dtReturn End Function
回答
SELECT IDColumn, NumberOfColumnsGreaterThanThree = (CASE WHEN Column1 >= 3 THEN 1 ELSE 0 END) + (CASE WHEN Column2 >= 3 THEN 1 ELSE 0 END) + (Case WHEN Column3 >= 3 THEN 1 ELSE 0 END) FROM TableA;