0

データの行を列に変換するのに助けが必要です。

私の各行は8つの列で構成されており、そのすべてを最終的な列リストに含めたいと思います。

通常、特定の価格設定行(約11)を返すために、次のようなselectステートメントを記述します。ProductID

SELECT  
    ProductID,
    PricingID, 
    COSBeginQty ,
    COSCOLCode,
    COSTrade,
    COSTypeOfPrice,
    COSIsActive, 
    COSPrice,
    COSPriceTAG,
    RowIndex
FROM 
    Pricing
Where 
    ProductID = XXXXX

返された各行には、すべての戻り値を表示したいものがあります。

ProductID, 
CosBeginQty1 COSBeginQty1  COSCOLCode1 COSTrade1 COSTypeOfPrice1 COSIsActive1 COSPrice1 COSPriceTAG1  
CosBeginQty2 COSBeginQty2  COSCOLCode2 COSTrade2 COSTypeOfPrice2 COSIsActive2 COSPrice2 COSPriceTAG2  
CosBeginQty3, COSBeginQty3  COSCOLCode3 COSTrade3 COSTypeOfPrice3 COSIsActive3 COSPrice3 COSPriceTAG3   . . . . 

。。。(11行すべてから必要な値を数えると、合計89列になります)列

これが私のテーブルのスクリプトです

CREATE TABLE [dbo].[Pricing](
    [ProductID] [uniqueidentifier] NOT NULL,
    [PricingID] [uniqueidentifier] NULL,
    [COSBeginQty] [int] NULL,
    [COSCOLCode] [nvarchar](50) NULL,
    [COSTrade] [nvarchar](50) NULL,
    [COSTypeOfPrice] [nchar](10) NULL,
    [COSIsActive] [bit] NULL,
    [COSPrice] [decimal](12, 3) NULL,
    [COSPriceTAG] [uniqueidentifier] NULL,
    [RowIndex] [int] NULL,
    [COSCreateDate] [datetime] NULL,
    [COSLastModifiedDate] [datetime] NULL,
 CONSTRAINT [PK_Pricing] PRIMARY KEY CLUSTERED 
(
    [ProductID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

GO
INSERT [dbo].[Pricing] ([ProductID], [PricingID], [COSBeginQty], [COSCOLCode], [COSTrade], [COSTypeOfPrice], [COSIsActive], [COSPrice], [COSPriceTAG], [RowIndex], [COSCreateDate], [COSLastModifiedDate]) VALUES (N'99533f6e-218f-48ef-bf01-03ea7808f9b1', N'5d8de11a-2399-4c68-87cd-4969827bed27', 7, N'MAN', N'T1', N'B         ', 1, CAST(23.400 AS Decimal(12, 3)), N'bf1d79bf-a60d-4603-8c2d-04492e9e1575', 1, NULL, NULL)
GO
INSERT [dbo].[Pricing] ([ProductID], [PricingID], [COSBeginQty], [COSCOLCode], [COSTrade], [COSTypeOfPrice], [COSIsActive], [COSPrice], [COSPriceTAG], [RowIndex], [COSCreateDate], [COSLastModifiedDate]) VALUES (N'94d67d13-e4e6-4360-9b7a-1cef7d997297', N'5ba0a6e9-53ed-4b9c-a9eb-2b09c41eb56c', 2, N'MAN', N'T2', N'A         ', 1, CAST(3456.234 AS Decimal(12, 3)), N'6ce7d421-e49a-469f-ae4c-a8bbb2f432fc', 3, NULL, NULL)
GO
INSERT [dbo].[Pricing] ([ProductID], [PricingID], [COSBeginQty], [COSCOLCode], [COSTrade], [COSTypeOfPrice], [COSIsActive], [COSPrice], [COSPriceTAG], [RowIndex], [COSCreateDate], [COSLastModifiedDate]) VALUES (N'e2216b52-66a9-4c29-a8ec-83c6ae03cd18', N'a8c27e9a-120c-47f2-bdd9-3e9e934ca237', 12, N'TEM', N'T1', N'B         ', 1, CAST(7234.000 AS Decimal(12, 3)), N'555c0f25-6af9-4114-8f11-096f0e5c7bcd', 1, NULL, NULL)
GO
ALTER TABLE [dbo].[Pricing] ADD  CONSTRAINT [DF_Pricing_ProductID]  DEFAULT (newid()) FOR [ProductID]
GO
ALTER TABLE [dbo].[Pricing] ADD  CONSTRAINT [DF_Pricing_PricingID]  DEFAULT (newid()) FOR [PricingID]
GO
ALTER TABLE [dbo].[Pricing] ADD  CONSTRAINT [DF_Pricing_COSPriceTAG]  DEFAULT (newid()) FOR [COSPriceTAG]
GO

問題の解決策は、BLUEFEETのおかげです。

select *, row_number() over(partition by ProductID order by ProductID) rn
from dbo.pricing;

DECLARE @colsUnpivot AS NVARCHAR(MAX),
    @query  AS NVARCHAR(MAX),
    @colsPivot as  NVARCHAR(MAX)

select @colsUnpivot = stuff((select ','+quotename(C.name)
         from sys.columns as C
         where C.object_id = object_id('Pricing') and
               C.name LIKE '%COS%'
               and C.name Not in ('COSCreateDate', 'COSLastModifiedDate')
         for xml path('')), 1, 1, '')

select @colsPivot = STUFF((SELECT  ',' 
                      + quotename(c.name 
                         + cast(t.rn as varchar(10)))
                    from
                    (
                      select row_number() over(partition by productid 
                                               order by productid) rn
                      from Pricing
                    ) t
                     cross apply 
                      sys.columns as C
                   where C.object_id = object_id('Pricing') and
                         C.name LIKE '%COS%'
                     and C.name Not in ('COSCreateDate', 'COSLastModifiedDate')
                   group by c.name, t.rn
                   order by t.rn
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

set @query 
  = 'select *
      from
      (
        select ProductID,
            col + cast(rn as varchar(10)) new_col,
            val
        from 
        (
          select ProductID,
              PricingID, 
              cast(COSBeginQty as varchar(50)) COSBeginQty,
              cast(COSCOLCode as varchar(50)) COSCOLCode,
              cast(COSTrade as varchar(50)) COSTrade,
              cast(COSTypeOfPrice as varchar(50)) COSTypeOfPrice,
              cast(COSIsActive as varchar(50)) COSIsActive, 
              cast(COSPrice as varchar(50)) COSPrice,
              cast(COSPriceTAG as varchar(50)) COSPriceTAG,
              RowIndex,
              row_number() over(partition by productid 
                                               order by productid) rn
          from Pricing
        ) x
        unpivot
        (
          val
          for col in ('+ @colsunpivot +')
        ) u
      ) x1
      pivot
      (
        max(val)
        for new_col in
          ('+ @colspivot +')
      ) p'

exec(@query)
4

2 に答える 2

2

完全なテーブル構造やサンプル データを確認しなくても、動的 SQL を使用してこのようなことができるように見えます。これは、 と の両方UNPIVOTを使用PIVOTして結果を取得します。

DECLARE @colsUnpivot AS NVARCHAR(MAX),
    @query  AS NVARCHAR(MAX),
    @colsPivot as  NVARCHAR(MAX)

再ピボット@colsUnpivotする必要がある列のリストを取得する最初の部分。結果にこれらの各列の複数のバージョンを含めるUNPIVOT必要があるため、必要です-UNPIVOTCosBeginQty1, CosBeginQty2, CosBeginQty3

select @colsUnpivot = stuff((select ','+quotename(C.name)
         from sys.columns as C
         where C.object_id = object_id('Pricing') and
               C.name LIKE '%COS%'
         for xml path('')), 1, 1, '')

を取得するコード@colsPivotは、最後の列を取得しています。これらの値 ( ) は、テーブルの各行に を CosBeginQty1, CosBeginQty2, CosBeginQty3適用することによって取得されます。row_number

select @colsPivot = STUFF((SELECT  ',' 
                      + quotename(c.name 
                         + cast(t.rn as varchar(10)))
                    from
                    (
                      select row_number() over(partition by productid 
                                               order by productid) rn
                      from Pricing
                    ) t
                     cross apply 
                      sys.columns as C
                   where C.object_id = object_id('Pricing') and
                         C.name LIKE '%COS%'
                   group by c.name, t.rn
                   order by t.rn
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

この最後の部分は、実行する動的 SQL ステートメントを生成します。と の両方の値を使用して、@colsUnpivotクエリ@colsPivotを実行する最終的な SQL ステートメントを形成します。

set @query 
  = 'select *
      from
      (
        select ProductID, PricingID, RowIndex,
            col + cast(rn as varchar(10)) new_col,
            val
        from 
        (
          select ProductID,
              PricingID, 
              COSBeginQty,
              COSCOLCode,
              COSTrade,
              COSTypeOfPrice,
              COSIsActive, 
              COSPrice,
              COSPriceTAG,
              RowIndex,
              row_number() over(partition by productid 
                                               order by productid) rn
          from Pricing
        ) x
        unpivot
        (
          val
          for col in ('+ @colsunpivot +')
        ) u
      ) x1
      pivot
      (
        max(val)
        for new_col in
          ('+ @colspivot +')
      ) p'

exec(@query)

このソリューションはrow_number()、各値に a を関連付け、次にUNPIVOTs を列に関連付け、最後にPIVOTsrow_number()を各列名に追加して関連付けます。

A PIVOTandUNPIVOTは静的に実行できますが、値の数が不明であるPIVOTため、動的バージョンを使用する必要があります。静的バージョンを使用していた場合、次のようになります。

select *
from
(
   select ProductID, PricingID, RowIndex,
      col + cast(rn as varchar(10)) new_col,
      val
   from 
   (
     select ProductID,
         PricingID, 
         COSBeginQty,
         COSCOLCode,
         COSTrade,
         COSTypeOfPrice,
         COSIsActive, 
         COSPrice,
         COSPriceTAG,
         RowIndex,
         row_number() over(partition by productid 
                                               order by productid) rn
     from Pricing
   ) x
   unpivot
   (
      val
      for col in (COSBeginQty, COSCOLCode, COSTrade, COSTypeOfPrice
                 COSIsActive, COSPrice, COSPriceTAG)
   ) u
) x1
pivot
(
   max(val)
   for new_col in ([COSBeginQty1], [COSCOLCode1], [COSTrade1], [COSTypeOfPrice1],
                   [COSIsActive1], [COSPrice1], [COSPriceTAG1],
                  [COSBeginQty2], [COSCOLCode2], [COSTrade2], [COSTypeOfPrice2],
                   [COSIsActive2], [COSPrice2], [COSPriceTAG2])
) p

編集 #2、サンプル データを適用すると、スクリプトは次のようになります。

DECLARE @colsUnpivot AS NVARCHAR(MAX),
    @query  AS NVARCHAR(MAX),
    @colsPivot as  NVARCHAR(MAX)

select @colsUnpivot = stuff((select ','+quotename(C.name)
         from sys.columns as C
         where C.object_id = object_id('Pricing') and
               C.name LIKE '%COS%'
               and C.name Not in ('COSCreateDate', 'COSLastModifiedDate')
         for xml path('')), 1, 1, '')

select @colsPivot = STUFF((SELECT  ',' 
                      + quotename(c.name 
                         + cast(t.rn as varchar(10)))
                    from
                    (
                      select row_number() over(partition by productid 
                                               order by productid) rn
                      from Pricing
                    ) t
                     cross apply 
                      sys.columns as C
                   where C.object_id = object_id('Pricing') and
                         C.name LIKE '%COS%'
                     and C.name Not in ('COSCreateDate', 'COSLastModifiedDate')
                   group by c.name, t.rn
                   order by t.rn
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

set @query 
  = 'select *
      from
      (
        select ProductID, PricingID, RowIndex,
            col + cast(rn as varchar(10)) new_col,
            val
        from 
        (
          select ProductID,
              PricingID, 
              cast(COSBeginQty as varchar(50)) COSBeginQty,
              cast(COSCOLCode as varchar(50)) COSCOLCode,
              cast(COSTrade as varchar(50)) COSTrade,
              cast(COSTypeOfPrice as varchar(50)) COSTypeOfPrice,
              cast(COSIsActive as varchar(50)) COSIsActive, 
              cast(COSPrice as varchar(50)) COSPrice,
              cast(COSPriceTAG as varchar(50)) COSPriceTAG,
              RowIndex,
              row_number() over(partition by productid 
                                               order by productid) rn
          from Pricing
        ) x
        unpivot
        (
          val
          for col in ('+ @colsunpivot +')
        ) u
      ) x1
      pivot
      (
        max(val)
        for new_col in
          ('+ @colspivot +')
      ) p'

exec(@query)

デモで SQL Fiddle を参照してください

于 2012-09-23T16:20:47.430 に答える
-1

動的SQLを使用できる場合は、これで十分です。

DECLARE @OUTPUT NVARCHAR(MAX)
SET @OUTPUT = "XXXXX"
SELECT @OUTPUT = @OUTPUT + "," + PricingID + COSBeginQty + COSCOLCode + COSTrade + COSTypeOfPrice + COSIsActive + COSPrice + COSPriceTAG + RowIndex
FROM Pricing
Where ProductID = XXXXX
于 2012-09-23T16:56:57.840 に答える