2

我有以下数据

替代文字

如何将它(使用 SQL Server 2005)转换为以下格式?

替代文字

我有一个我想出的示例解决方案,但它似乎有点笨拙。可能有味道?

DECLARE @ProductLanguage TABLE
(
    [PRODUCT_ID] int
    , [LANGUAGE] varchar(50)
)

INSERT INTO @ProductLanguage ([PRODUCT_ID],[LANGUAGE]) VALUES (52035,'Czech')
INSERT INTO @ProductLanguage ([PRODUCT_ID],[LANGUAGE]) VALUES (52035,'English')
INSERT INTO @ProductLanguage ([PRODUCT_ID],[LANGUAGE]) VALUES (52035,'German')
INSERT INTO @ProductLanguage ([PRODUCT_ID],[LANGUAGE]) VALUES (54001,'Danish')
INSERT INTO @ProductLanguage ([PRODUCT_ID],[LANGUAGE]) VALUES (54001,'Spanish')
INSERT INTO @ProductLanguage ([PRODUCT_ID],[LANGUAGE]) VALUES (54001,'English')
INSERT INTO @ProductLanguage ([PRODUCT_ID],[LANGUAGE]) VALUES (70501,'Finnish')
INSERT INTO @ProductLanguage ([PRODUCT_ID],[LANGUAGE]) VALUES (70501,'Greek')
INSERT INTO @ProductLanguage ([PRODUCT_ID],[LANGUAGE]) VALUES (70501,'Hungarian')
INSERT INTO @ProductLanguage ([PRODUCT_ID],[LANGUAGE]) VALUES (52044,'Hebrew')

SELECT
    PRODUCT_ID
    ,MAX(CASE WHEN [ROW_ID]=1 THEN LANGUAGE ELSE NULL END) As LANG_1
    ,MAX(CASE WHEN [ROW_ID]=2 THEN LANGUAGE ELSE NULL END) As LANG_2
    ,MAX(CASE WHEN [ROW_ID]=3 THEN LANGUAGE ELSE NULL END) As LANG_3
FROM
    (SELECT
        ROW_NUMBER() OVER (PARTITION BY [PRODUCT_ID] ORDER BY [PRODUCT_ID] ASC) AS [ROW_ID]
        , [PRODUCT_ID]
        , [LANGUAGE]
    FROM
        @ProductLanguage) AS Temp
GROUP BY
    [PRODUCT_ID]

有趣的是我不关心每个 LANG_* 列中显示的特定语言。此处发布的其他问题似乎都涉及按名称了解旋转列。但我不想用找到的语言来命名列。

注意:我知道我提到了“pivot”这个词,但这个问题的最佳解决方案可能不涉及 PIVOT 子句。我只是使用了这个词,因为我的问题似乎暗示了数据透视。也许 CTE 会帮助解决问题,我不知道。我只知道我对上面的示例解决方案不满意。

4

4 回答 4

3

您可以使用 PIVOT() 函数

SELECT    P.PRODUCT_ID,
          P.Czech,
          P.Other languages
FROM      TABLE AS T
PIVOT     (
              AGGREGATE(LANGUAGE) FOR LANGUAGE IN ([Czech],  ...)
          ) AS P

如果您没有明确命名列,据我所知,您将被迫做一些技巧......

未经测试(显然)。参见: MSDN

于 2008-12-19T03:06:50.823 回答
1

这可以通过PIVOT静态或动态的 a 来完成。

静态版本的列是硬编码的(参见SQL Fiddle with Demo):

select *
from 
(
  select product_id, language,
    'Lang_' + cast(row_number() over(partition by PRODUCT_ID order by language) as varchar(10)) rn
  from ProductLanguage
) x
pivot
(
  max(language)
  for rn in ([Lang_1], [Lang_2], [Lang_3])
) p

动态版本将在运行时获取列(参见SQL Fiddle With Demo):

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

select @cols = STUFF((SELECT distinct ',' + QUOTENAME('Lang_' + cast(row_number() over(partition by PRODUCT_ID order by language) as varchar(10))) 
                    from ProductLanguage
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')


set @query = 'SELECT PRODUCT_ID, ' + @cols + ' from 
             (
              select product_id, language,
                ''Lang_'' + cast(row_number() over(partition by PRODUCT_ID order by language) as varchar(10)) rn
              from ProductLanguage
            ) x
            pivot 
            (
                max(language)
                for rn in (' + @cols + ')
            ) p '

execute(@query)
于 2012-09-21T03:00:42.420 回答
0

这是一个想法……使用 Pivot 关键字……在 sql2005 中可用

枢轴和取消枢轴

然后在你完成这项工作后,将列名作为数据值输出,将整个 sql statemnt 作为子查询嵌入到外部 Select 语句中,你将列名命名为“Language1”、“Language2”等...

Select Z.Arabic as Language1, Z.Botwanese as Language2, etc.
From  (Inner Pivot Query Here ) Z
于 2008-12-19T02:52:34.767 回答
0
create table  #ProductLanguage 
(
    PRODUCT_ID int
    , [LANGUAGE] varchar(50)
)

INSERT INTO #ProductLanguage  ([PRODUCT_ID],[LANGUAGE]) VALUES (52035,'Czech')
INSERT INTO #ProductLanguage  ([PRODUCT_ID],[LANGUAGE]) VALUES (52035,'English')
INSERT INTO #ProductLanguage  ([PRODUCT_ID],[LANGUAGE]) VALUES (52035,'German')
INSERT INTO #ProductLanguage  ([PRODUCT_ID],[LANGUAGE]) VALUES (54001,'Danish')
INSERT INTO #ProductLanguage  ([PRODUCT_ID],[LANGUAGE]) VALUES (54001,'Spanish')
INSERT INTO #ProductLanguage  ([PRODUCT_ID],[LANGUAGE]) VALUES (54001,'English')
INSERT INTO #ProductLanguage  ([PRODUCT_ID],[LANGUAGE]) VALUES (70501,'Finnish')
INSERT INTO #ProductLanguage  ([PRODUCT_ID],[LANGUAGE]) VALUES (70501,'Greek')
INSERT INTO #ProductLanguage  ([PRODUCT_ID],[LANGUAGE]) VALUES (70501,'Hungarian')
INSERT INTO #ProductLanguage  ([PRODUCT_ID],[LANGUAGE]) VALUES (52044,'Hebrew')


declare @col as varchar(2000)
declare @query as varchar(4000)

--select language ,@col= replace('[Lang_'+str(row_number() over(order by language))+']',' ','') Lang  from (select distinct language  from #ProductLanguage)p
select  @col = stuff((select distinct '],['+language  from #ProductLanguage for xml path('')),1,2,'')+']' 
print @col

set @query = 'select PRODUCT_ID, '+@col+ ' from #ProductLanguage 
pivot (
max(LANGUAGE) for LANGUAGE in ('+@col+')
) pvt'
execute(@query)
于 2013-09-25T14:18:13.833 回答