質問

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

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

TableA
Column1, Column2, Column3

実行するSQL文

ResultA
Value of Column1
Value of Column2
Value of Column3

@ケビン: このトピックについて Google で検索しましたが、私の例ではあまりにも複雑すぎる例が多かったので、 さらにお手伝いできますか?

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

役に立ちましたか?

解決

UNPIVOT 句を確認してください。

アップデート1:GateKiller 、奇妙なことに、今朝それに関する記事 (関係のないことについての) を読み、もう一度見たときの記憶をたどろうとしているのですが、まともな例もいくつかありました。きっと自分に返ってくるよ。

アップデート2:それを見つけた: http://weblogs.sqlteam.com/jeffs/archive/2008/04/23/unpivot.aspx

他のヒント

以前、プロジェクトでこれを行う必要がありました。私が抱えていた大きな困難の 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

連合 あなたの友達になるべきです:

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

でもそれはできます あなたも敵になってください 大規模な結果セットの場合。

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

(SELECT Column1 AS ResultA FROM TableA) as R1

そして副選択に参加します。これらすべてを 1 つのクエリで実行できます。

これに対する 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;

編集:非常に(非常に)短い Google 検索で、次のことがわかります。 CASE ステートメントは私がやっていることを行います IF MySQL のステートメント。使える場合もあれば、使えない場合もあります 私が見つけたGoogleの結果

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

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;
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top