Vă mulțumim pentru susținere

Cum pot transforma coloanele sql în rânduri?

Am o problemă foarte simplă, care necesită o soluție foarte rapidă și simplă în SQL Server 2005.

Am un tabel cu x Coloane. Vreau să pot selecta un rând din tabel și apoi să transforme coloanele în rânduri.

TableA
Column1, Column2, Column3

Instrucțiunea SQL pentru ruturn

ResultA
Value of Column1
Value of Column2
Value of Column3

@Kevin: I've had a google search on the topic but alot of the example where overly complex for my example, are you able to help further?

@Mario: The solution I am creating has 10 columns which stores the values 0 to 6 and I must work out how many columns have the value 3 or more. So I thought about creating a query to turn that into rows and then using the generated table in a subquery to say count the number of rows with Column >= 3

0
adăugat editat
Hm ... acum e ceva ce nu am încercat niciodată. Soluțiile care mi-au venit în minte sunt prea complicate și prea urâte și sunt sigur că e ceva mult mai elegant. Am făcut o căutare și pe UNPIVOT și se pare că este calea pe care ar trebui să o faceți. Îl iau pe acesta ca pe un puzzle pentru a rezolva în zilele următoare.
adăugat autor Mario Marinato
adăugat autor Dalex

5 răspunsuri

A trebuit să fac asta pentru un proiect înainte. Una dintre dificultățile majore pe care le aveam era explicarea a ceea ce încercam să fac altora. Am petrecut o tona de timp încercând să fac acest lucru în SQL, dar am găsit funcția de pivot nemaipomenită. Nu-mi amintesc exact motivul pentru care a fost, dar este prea simplist pentru majoritatea aplicațiilor și nu este implementat complet în MS SQL 2000. Am terminat scrierea unei funcții pivot în .NET. Îl voi posta aici, în speranța că o să ajute pe cineva, într-o bună zi.

 ''' 
''' Pivots a data table from rows to columns '''
 
    ''' 
The data table to be transformed
    ''' 
The name of the column that identifies each row
    ''' 
The name of the column with the values to be transformed from rows to columns
    ''' 
The name of the column with the values to pivot into the new columns
    ''' The transformed data table
    ''' 
    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
adăugat

Nu sunt sigur de sintaxa SQL Server pentru asta, dar în MySQL aș face

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

EDIT: A very (very) brief Google search tells me that the CASE statement does what I am doing with the IF statement in MySQL. You may or may not get use out of the Google result I found

FURTHER EDIT: De asemenea, trebuie să subliniez că acest lucru nu este un răspuns la întrebarea dvs., ci o soluție alternativă la problema dvs. reală.

0
adăugat

UNION should be your friend:

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

dar poate fi și dușmanul tău pe seturi de rezultate mari.

0
adăugat

Ar trebui să aruncați o privire la clauza UNPIVOT.

Update1: GateKiller, strangely enough I read an article (about something unrelated) about it this morning and I'm trying to jog my memory where I saw it again, had some decent looking examples too. It'll come back to me I'm sure.

Update2: Found it: http://weblogs.sqlteam.com/jeffs/archive/2008/04/23/unpivot.aspx

0
adăugat

Dacă aveți un set fix de coloane și știți ce sunt, puteți face o serie de subselecte

(SELECT Column1 AS ResultA FROM TableA) as R1

și să se alăture subselectelor. Toate acestea într-o singură interogare.

0
adăugat