Как Transform Sql столбцов на строки?

голоса
15

У меня есть очень простая задача, которая требует очень быстрое и простое решение, в SQL Server 2005.

У меня есть таблица с й столбцами. Я хочу, чтобы иметь возможность выбрать одну строку из таблицы, а затем преобразовать столбцы в строки.

TableA
Column1, Column2, Column3

SQL Заявление RUTURN

ResultA
Value of Column1
Value of Column2
Value of Column3

@Kevin: Я был поиск Google по этой теме , но много примера , где слишком сложные для моего примера, вы в состоянии помочь в дальнейшем?

@Mario: Решение я создаю имеет 10 столбцов, которые сохраняют значение от 0 до 6, и я должен работать, сколько столбцов имеют значение 3 или больше. Так я думал о создании запроса, чтобы превратить это в строки, а затем, используя сгенерированную таблицу в подзапросе сказать подсчитать количество строк с Column> = 3

Задан 06/08/2008 в 15:36
источник пользователем
На других языках...                            


6 ответов

голоса
5

Вы должны взглянуть на п UNPIVOT.

Update1 : GateKiller, как ни странно , я прочитал статью (о чем - то несвязанной) об этом сегодня утром , и я пытаюсь подталкивать мою память , где я видел его снова, имел некоторые достойные выглядящие примеры тоже. Он вернется ко мне , я уверен.

Update2 : Нашел: http://weblogs.sqlteam.com/jeffs/archive/2008/04/23/unpivot.aspx

Ответил 06/08/2008 в 15:39
источник пользователем

голоса
1

Я должен был сделать это для проекта прежде. Одна из основных трудностей, у меня был объяснить, что я пытался сделать для других людей. Я потратил массу времени, пытаясь сделать это в SQL, но я обнаружил, что функция поворота неадекватна. Я не помню точную причину, почему это было, но это слишком упрощенно для большинства приложений, и это не полный реализована в MS SQL 2000. Я ликвидируется написание функции поворота в .NET. Я выложу его здесь в надежде, что кто-то помогает, когда-нибудь.

 ''' <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
Ответил 06/08/2008 в 16:16
источник пользователем

голоса
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;
Ответил 26/09/2008 в 22:34
источник пользователем

голоса
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;

EDIT: очень (очень) проинструктировать поиск Google говорит мне , что CASEзаявление делает то , что я делаю с IFутверждением в MySQL. Вы можете или не можете получить пользы из результата Google я нашел

ДАЛЕЕ EDIT: Я хотел бы также отметить, что это не ответ на ваш вопрос, но альтернативное решение вашей конкретной проблемы.

Ответил 06/08/2008 в 15:59
источник пользователем

голоса
0

Если у вас есть фиксированный набор столбцов, и вы знаете, что они есть, вы можете в основном сделать серию подзапросов

(SELECT Column1 AS ResultA FROM TableA) as R1

и присоединиться к подзапросам. Все это в одном запросе.

Ответил 06/08/2008 в 15:41
источник пользователем

голоса
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

но это может также быть вашим врагом на больших наборах результатов.

Ответил 06/08/2008 в 15:39
источник пользователем

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