Vra

Ek het 'n baie eenvoudige probleem wat 'n baie vinnige en eenvoudige oplossing in SQL Server 2005 vereis.

Ek het 'n tabel met x kolomme.Ek wil een ry uit die tabel kan kies en dan die kolomme in rye omskep.

TableA
Column1, Column2, Column3

SQL-stelling om te ruturn

ResultA
Value of Column1
Value of Column2
Value of Column3

@Kevin: Ek het 'n Google-soektog oor die onderwerp gehad, maar baie van die voorbeelde was te kompleks vir my voorbeeld, kan jy verder help?

@Mario:Die oplossing wat ek skep het 10 kolomme wat die waardes 0 tot 6 stoor en ek moet uitwerk hoeveel kolomme die waarde 3 of meer het.Ek het dus daaraan gedink om 'n navraag te skep om dit in rye te verander en dan die gegenereerde tabel in 'n subnavraag te gebruik om te sê tel die aantal rye met Kolom >= 3

Was dit nuttig?

Oplossing

U moet na die UNPIVOT-klousule kyk.

Opdatering 1:GateKiller, vreemd genoeg het ek vanoggend 'n artikel (oor iets wat nie verband hou nie) daaroor gelees en ek probeer my geheue draf waar ek dit weer gesien het, het ook 'n paar ordentlike voorbeelde gehad.Dit sal na my toe terugkom, ek is seker.

Opdatering 2:Het dit gekry: http://weblogs.sqlteam.com/jeffs/archive/2008/04/23/unpivot.aspx

Ander wenke

Ek moes dit voorheen vir 'n projek doen.Een van die groot probleme wat ek gehad het, was om aan ander mense te verduidelik wat ek probeer doen het.Ek het baie tyd spandeer om dit in SQL te probeer doen, maar ek het gevind dat die spilpuntfunksie ongelukkig onvoldoende was.Ek onthou nie die presiese rede hoekom dit was nie, maar dit is te simplisties vir die meeste toepassings, en dit is nie volledig in MS SQL 2000 geïmplementeer nie.Ek het uiteindelik 'n spilfunksie in .NET geskryf.Ek sal dit hier plaas in die hoop dat dit iemand help, eendag.

 ''' <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

UNIE moet jou vriend wees:

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

maar dit kan wees ook jou vyand op groot resultatestelle.

As jy 'n vaste stel kolomme het en jy weet wat hulle is, kan jy basies 'n reeks subseleksies doen

(SELECT Column1 AS ResultA FROM TableA) as R1

en sluit aan by die subkies.Dit alles in 'n enkele navraag.

Ek is nie seker van die SQL Server-sintaksis hiervoor nie, maar in MySQL sou ek dit doen

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

EDIT:'n Baie (baie) kort Google-soektog vertel my dat die CASE stelling doen wat ek doen met die IF stelling in MySQL.Jy kan of mag nie gebruik maak van die Google-resultaat wat ek gevind het

VERDERE EDIT:Ek moet ook daarop wys dat dit nie 'n antwoord op jou vraag is nie, maar 'n alternatiewe oplossing vir jou werklike probleem.

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;
Gelisensieer onder: CC-BY-SA met toeskrywing
Nie verbonde aan StackOverflow
scroll top