我有一个非常简单的问题,需要在SQL Server 2005中提供一个非常快速和简单的解决方案。
我有一个带有x列的表。我希望能够从表中选择一行,然后将列转换为行。
TableA
Column1, Column2, Column3
ruturn的SQL语句
ResultA
Value of Column1
Value of Column2
Value of Column3
@Kevin:我已经对该主题进行了Google搜索,但很多示例中我的示例过于复杂,您是否能够进一步提供帮助? < / p>
@Mario:我正在创建的解决方案有10列,存储值0到6,我必须弄清楚有多少列的值为3或更多。所以我考虑创建一个查询来将其转换为行,然后使用子查询中生成的表来计算列数&gt; = 3
的行数答案 0 :(得分:5)
你应该看看UNPIVOT条款。
Update1 :GateKiller,奇怪的是我今天早上读了一篇关于它的文章(关于某些无关的内容),我试图慢慢记住我再次看到它的记忆,也看了一些体面的例子。它肯定会回到我的身边。
Update2 :找到它:http://weblogs.sqlteam.com/jeffs/archive/2008/04/23/unpivot.aspx
答案 1 :(得分:1)
之前我必须为一个项目做这件事。我遇到的一个主要困难是向其他人解释我想要做的事情。我花了很多时间在SQL中尝试这样做,但我发现枢轴功能严重不足。我不记得它的确切原因,但它对于大多数应用程序来说太简单了,并且它没有在MS SQL 2000中完全实现。我最终在.NET中编写了一个pivot函数。我会在这里发布,希望有一天能帮助某人。
''' <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
答案 2 :(得分:0)
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
但它可以在大型结果集上also be your foe。
答案 3 :(得分:0)
如果你有一组固定的列并且你知道它们是什么,你基本上可以做一系列的子选择
(SELECT Column1 AS ResultA FROM TableA) as R1
并加入子选择。所有这一切都在一个查询中。
答案 4 :(得分:0)
我不确定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
语句所做的事情。您可能会或可能不会使用the Google result I found
进一步编辑:我还应该指出,这不是您问题的答案,而是您实际问题的替代解决方案。
答案 5 :(得分:0)
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;