2008-08-06 62 views
13

Tôi có một vấn đề rất đơn giản đòi hỏi một giải pháp rất nhanh chóng và đơn giản trong SQL Server 2005.Làm cách nào để chuyển đổi các cột Sql thành hàng?

Tôi có một bảng với x Cột. Tôi muốn có thể chọn một hàng từ bảng và sau đó chuyển đổi các cột thành các hàng.

TableA 
Column1, Column2, Column3 

SQL Statement để ruturn

ResultA 
Value of Column1 
Value of Column2 
Value of Column3 

@Kevin: Tôi đã có một tìm kiếm google về chủ đề này nhưng rất nhiều ví dụ nơi quá phức tạp ví dụ của tôi, là bạn có thể giúp đỡ thêm?

@Mario: Giải pháp tôi đang tạo có 10 cột lưu trữ các giá trị 0 đến 6 và tôi phải tính ra số cột có giá trị 3 trở lên. Vì vậy, tôi đã nghĩ đến việc tạo truy vấn để chuyển thành hàng và sau đó sử dụng bảng được tạo trong truy vấn con để nói số lượng hàng có Cột> = 3

+0

Nhìn vào blog của tôi: http://sql-tricks.blogspot.com/2011/04/sql-server-rows-transpose.html – Dalex

+0

Hm ... bây giờ đó là điều mà tôi đã không bao giờ thử. Các giải pháp đến với tâm trí của tôi là tất cả quá khó khăn và quá xấu xí, và tôi chắc chắn có một cái gì đó thanh lịch hơn nhiều. Tôi cũng đã tìm kiếm trên UNPIVOT và có vẻ như đó là con đường bạn nên đi. Tôi sẽ lấy cái này như một câu đố để giải quyết trong những ngày tiếp theo. –

Trả lời

5

Bạn nên xem xét mệnh đề UNPIVOT.

Update1: GateKiller, kỳ lạ là tôi đã đọc một bài báo (về một thứ gì đó không liên quan) về sáng nay và tôi đang cố gắng chạy bộ nhớ của mình khi tôi nhìn thấy nó một lần nữa. Nó sẽ trở lại với tôi tôi chắc chắn.

Update2: Tìm thấy nó: http://weblogs.sqlteam.com/jeffs/archive/2008/04/23/unpivot.aspx

0

UNION nên bạn của bạn:

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 

nhưng nó có thể also be your foe trên bộ kết quả lớn.

0

Nếu bạn có một tập cố định các cột và bạn biết những gì họ đang có, về cơ bản bạn có thể làm một loạt các subselects

(SELECT Column1 AS ResultA FROM TableA) as R1

và tham gia vào subselects. Tất cả điều này trong một truy vấn.

0

Tôi không chắc chắn của các cú pháp SQL Server cho điều này nhưng trong MySQL tôi sẽ làm

SELECT IDColumn, (IF(Column1 >= 3, 1, 0) + IF(Column2 >= 3, 1, 0) + IF(Column3 >= 3, 1, 0) + ... [snip ]) 
    AS NumberOfColumnsGreaterThanThree 
FROM TableA; 

EDIT: Một rất (rất) ngắn gọn tìm kiếm của Google nói với tôi rằng tuyên bố CASE làm những gì tôi đang làm với câu lệnh IF trong MySQL. Bạn có thể hoặc không được sử dụng trong số the Google result I found

THÊM EDIT: Tôi cũng nên chỉ ra rằng đây không phải là câu trả lời cho câu hỏi của bạn mà là giải pháp thay thế cho vấn đề thực tế của bạn.

1

Tôi phải làm điều này cho một dự án trước đây. Một trong những khó khăn chính tôi đã giải thích những gì tôi đang cố gắng làm cho người khác. Tôi đã dành rất nhiều thời gian cố gắng để làm điều này trong SQL, nhưng tôi thấy các chức năng pivot woefully không đủ. Tôi không nhớ chính xác lý do tại sao nó được, nhưng nó là quá đơn giản cho hầu hết các ứng dụng, và nó không phải là đầy đủ thực hiện trong MS SQL 2000. Tôi vết thương lên viết một chức năng pivot trong NET. Tôi sẽ đăng nó ở đây với hy vọng nó sẽ giúp ai đó, một ngày nào đó.

''' <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 
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; 
Các vấn đề liên quan