Como posso transformar Colunas SQL em linhas?

votos
15

Eu tenho um problema muito simples que requer uma solução muito rápida e simples no SQL Server 2005.

Eu tenho uma tabela com x Colunas. Eu quero ser capaz de selecionar uma linha da tabela e, em seguida, transformar as colunas em linhas.

TableA
Column1, Column2, Column3

Declaração SQL para ruturn

ResultA
Value of Column1
Value of Column2
Value of Column3

@ Kevin: Eu tive uma pesquisa no Google sobre o tema, mas um monte de exemplo onde excessivamente complexa para o meu exemplo, você é capaz de ajudar ainda mais?

@Mario: A solução que eu estou criando tem 10 colunas que armazena os valores 0 a 6 e devo trabalhar para fora como muitas colunas têm o valor de 3 ou mais. Então eu pensei sobre a criação de uma consulta para transformar isso em filas e, em seguida, usando a tabela gerada em uma subconsulta para dizer contar o número de linhas com coluna> = 3

Publicado 06/08/2008 em 15:36
fonte usuário
Em outras línguas...                            


6 respostas

votos
5

Você deve dar uma olhada na cláusula UNPIVOT.

Update1 : GateKiller, estranhamente eu li um artigo (sobre algo não relacionado) sobre isso esta manhã e eu estou tentando fazer jogging minha memória onde eu vi isso de novo, teve alguns exemplos que procuram decentes também. Ele vai voltar para mim, tenho certeza.

Atualização2 : Encontrado que: http://weblogs.sqlteam.com/jeffs/archive/2008/04/23/unpivot.aspx

Respondeu 06/08/2008 em 15:39
fonte usuário

votos
1

Eu tive que fazer isso para um projeto antes. Uma das maiores dificuldades que tive foi explicando o que eu estava tentando fazer com outras pessoas. Eu passei uma tonelada de tempo tentando fazer isso em SQL, mas eu achei a função de pivô lamentavelmente inadequada. Não me lembro exatamente o motivo por que era, mas é simplista demais para a maioria das aplicações, e não é completa implementado em MS SQL 2000. acabei escrevendo uma função de pivô em .NET. Vou postar aqui na esperança de que ajude alguém, algum dia.

 ''' <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
Respondeu 06/08/2008 em 16:16
fonte usuário

votos
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;
Respondeu 26/09/2008 em 22:34
fonte usuário

votos
0

Eu não tenho certeza da sintaxe SQL Server para isso, mas no MySQL eu faria

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

EDIT: A muito (muito) breve pesquisa Google me diz que a CASEdeclaração faz o que eu estou fazendo com a IFdeclaração em MySQL. Você pode ou não pode ficar fora de uso o resultado Google eu encontrei

Editar mais: Eu também salientar que esta não é uma resposta à sua pergunta, mas uma solução alternativa para o problema real.

Respondeu 06/08/2008 em 15:59
fonte usuário

votos
0

Se você tem um conjunto fixo de colunas e você sabe o que são, basicamente você pode fazer uma série de subselects

(SELECT Column1 AS ResultA FROM TableA) as R1

e juntar-se aos subselects. Tudo isso em uma única consulta.

Respondeu 06/08/2008 em 15:41
fonte usuário

votos
0

UNIÃO deve ser seu amigo:

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

mas pode também ser o seu inimigo em grandes conjuntos de resultados.

Respondeu 06/08/2008 em 15:39
fonte usuário

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more