2

1行のデータを返すクエリがあります。このように見えるとしましょう(列ヘッダー付き)。

Fruit    | Veg     | Meats   | Nuts    |
----------------------------------------
Apple      Lettuce   Veal      Almond

これの代わりに、この単一の行を2列のテーブルとして返し、列/フィールド名を左端の列に配置します。そのようです:

FieldName  | Value    |
-----------------------
Fruit        Apple
Veg          Lettuce
Meats        Veal
Nuts         Almond

これを実現するための痛みを伴わない方法があるはずですが、ある場合はそれを見つけることができないようです。レンガの壁にぶつかる。これも可能ですか?

ご入力いただきありがとうございます。

編集: クエリは静的ではない結果を返すため、列見出しを明示的に定義することはできません。

編集2: 私はこれらの提案のいくつかを機能させようとしていますが、それでもこれを複数の列で機能させることができません。これが私のコードです:

SELECT
  TOP 10
  FieldName,
  CAST(FieldValue as varchar(MAX)) As FieldValue
FROM Meter M
UNPIVOT([FieldValue] FOR FieldName IN ([MeterName],[MID])) UP
WHERE ClientNumber = 12300

毎回、「メッセージ8167、レベル16、状態1、行4」というエラーが表示されます。列「MID」のタイプが、UNPIVOTリストで指定されている他の列のタイプと競合しています。

これを調べましたが、列の種類/長さに関連する問題のようです。FieldValueをどのようにキャストしても、同じエラーが発生します。何か考えはありますか?

編集3:列の競合の解決...

元のテーブルからのキャスト結果は機能しないため、派生テーブルを使用して、PIVOTに返される列がすべて同じデータ型になるようにキャストする必要がありました。奇妙ですが、私が見つけた唯一の解決策は実行されるでしょう。

SELECT
  FieldName,
  CAST(FieldValue as varchar(MAX)) As FieldValue,
FROM 
(
  /* 
  Derived table so that we can control the column
  types for everything selected, because PIVOT demands
  that every pivoted column be of the same data type and
  length.
  */
  SELECT
    TOP 1
    CAST(M.MeterName as varchar(MAX)) As MeterName,
    CAST(M.MID as varchar(MAX)) As MID,
    CAST(D.DeviceType as varchar(MAX)) As DeviceType
  FROM Meter M
    INNER JOIN CurrentDevice D ON
      D.ClientNumber = M.ClientNumber AND
      D.MID = M.MID
  WHERE 
    M.ClientNumber = 12300
) T
UNPIVOT([FieldValue] FOR FieldName IN ([MeterName],[MID],[DeviceType])) UP
4

3 に答える 3

8

SQL Server 2005以降では、次を使用できますUNPIVOT

SELECT FieldName, Value
FROM YourTable T
UNPIVOT([Value] FOR FieldName IN (Fruit, Veg, Meats, Nuts)) UP

これがあなたが試すためのSQLフィドルです。

新しい要件に合わせて更新

テーブルの列がわからない場合は、動的SQLが必要です。まず、このリンクにアクセスします。次に、次のことを試すことができます。

DECLARE @Fields NVARCHAR(MAX), @Sql NVARCHAR(MAX)

SELECT @Fields = STUFF((SELECT DISTINCT ',' + QUOTENAME(Name) 
                        FROM sys.columns
                        WHERE OBJECT_ID = OBJECT_ID('YourTable')
                        FOR XML PATH('')),1,1,'')


SET @Sql = '
SELECT FieldName, Value
FROM YourTable T
UNPIVOT([Value] FOR FieldName IN ('+@Fields+')) UP
'

EXEC sp_executesql @sql
于 2012-08-28T14:07:37.930 に答える
4

動的なUNPIVOTクエリを使用できます

DECLARE @cols AS NVARCHAR(MAX),
    @query  AS NVARCHAR(MAX)

select @cols =  STUFF((SELECT ','+ QUOTENAME( name) from sys.columns 
where object_id= object_id('your_table')
FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

set @query = 'select FieldName, Value
FROM your_table T
UNPIVOT([Value] FOR FieldName IN ('+@cols+')) P'

exec(@query)


SQLフィドルデモ

于 2012-08-28T14:20:06.790 に答える
0

これに使用できます:http PIVOT//msdn.microsoft.com/en-us/library/ms177410 (v = sql.105).aspx 。

于 2012-08-28T13:54:11.357 に答える