17

SQL Server 2005 で非常に迅速かつ簡単な解決策を必要とする非常に単純な問題があります。

x列のテーブルがあります。テーブルから 1 つの行を選択して、列を行に変換できるようにしたいと考えています。

TableA
Column1, Column2, Column3

戻るSQL文

ResultA
Value of Column1
Value of Column2
Value of Column3

@Kevin:このトピックについて Google 検索を行ったことがありますが、私の例では非常に複雑な例がたくさんあります。さらにお手伝いできますか?

@マリオ:私が作成しているソリューションには、値0から6を格納する10列があり、3以上の値を持つ列の数を計算する必要があります。そこで、クエリを作成してそれを行に変換し、生成されたテーブルをサブクエリで使用して、Column >= 3 の行数をカウントすることを考えました。

4

6 に答える 6

6

UNPIVOT 句を確認する必要があります。

Update1 : GateKiller、不思議なことに、今朝それに関する記事 (無関係なものについて) を読んだので、もう一度見た場所を思い出そうとしていますが、見栄えの良い例もいくつかありました。きっと私の元に戻ってきます。

Update2 : 見つけました: http://weblogs.sqlteam.com/jeffs/archive/2008/04/23/unpivot.aspx

于 2008-08-06T14:39:09.457 に答える
1

私は以前にプロジェクトのためにこれをしなければなりませんでした。私が抱えていた主な困難の 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
于 2008-08-06T15:16:32.223 に答える
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検索では、ステートメントがMySQLCASEのステートメントで行っていることを実行していることがわかります。私が見つけた Google の結果をIF利用できる場合と利用できない場合があります

さらに編集:これはあなたの質問に対する答えではなく、実際の問題に対する代替解決策であることも指摘する必要があります。

于 2008-08-06T14:59:36.547 に答える
0

ユニオンはあなたの友達であるべきです:

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

しかし、大規模な結果セットでは敵になる可能性もあります。

于 2008-08-06T14:39:17.837 に答える
0

列の固定セットがあり、それらが何であるかを知っている場合、基本的に一連の副選択を行うことができます

(SELECT Column1 AS ResultA FROM TableA) as R1

サブセレクトに参加します。これらすべてを 1 つのクエリで実行できます。

于 2008-08-06T14:41:29.280 に答える
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;
于 2008-09-26T21:34:22.083 に答える