7

我正在尝试将桌子旋转 90 度:使列成为行。不允许 PIVOT,因为 PIVOT 需要聚合函数。

示例:我有一个包含以下列的表:
ID int、
ISO char(2)、
Text varchar(255)。

所以我有这个:

ID ISO 文本
-- ---- ----
 1 DE 自动
 2 CN 汽车

我想得到以下内容:

ID EN DE
-- ---- ----
 1 汽车 汽车

你如何做到这一点?

4

6 回答 6

5

This answer is really frantisek's, I'm just copying here to correct the mistake (I can't edit directly).

Basically, you use that solution, with a tweak:

SELECT 
    max(DE) as DE, max(EN) as EN 
FROM 
    test 
PIVOT (MAX([text]) FOR ISO in (DE,EN)) p

This will get the content into a single row. Also, it drops the ID, since it doesn't make sense if you want a single row (there is no logic to indicate what to do with it when combining into a single row).

Also, the assumption is made that the values in the ISO column are unique, otherwise, this will lose data due to the MAX aggregate.

于 2009-01-09T14:58:18.887 回答
2

I found the solution as the following:

SELECT 
    ID, DE, EN
FROM 
    TextTable 
PIVOT(MAX([text]) FOR ISO IN (DE,EN)) p

It's possible to use PIVOT with MAX aggregating function over the text.

于 2009-01-09T14:53:46.663 回答
1

Query without a PIVOT even though other answers prove you can use a PIVOT :)

SELECT
    MAX(DE.Text) AS DE,
    MAX(EN.Text) AS EN  
FROM TextTable AS TT
LEFT JOIN TextTable AS DE
    ON DE.ID = TT.ID
    AND DE.ISO = 'DE'
LEFT JOIN TextTable AS EN
    ON EN.ID = TT.ID
    AND EN.ISO = 'EN'
于 2009-01-09T15:14:25.843 回答
1

如果您尝试此解决方案并遇到语法错误,请尝试通过以下方式设置数据库的兼容模式

ALTER DATABASE myDatabase SET COMPATIBILITY_LEVEL = 90;

这会将兼容性设置为 SQLServer 2005,并且上述查询将执行 w/oa 语法错误。

于 2012-02-06T20:02:43.483 回答
1
select 
   t.num_claim_no,
   rtrim (xmlagg (xmlelement (e, t.txt_remarks ||'@'|| t.dat_update_date || '  ,  ')).extract ('//text()'), ',') Remarks,
   rtrim (xmlagg (xmlelement (e, t.num_update_no || ' , ')).extract ('//text()'), ',') SrlNo
from 
   gc_clm_gen_info t
   where t.txt_remarks is not null
  group by 
   t.num_claim_no
;
于 2012-02-20T07:46:31.373 回答
0

由于您明确要求使用非枢轴解决方案:如果您知道行中将拥有哪些 ISO,这应该可以工作。我称该表为“测试”。

declare @temp table ([ID] int, [de] varchar(255), [en] varchar(255)) -- add ISOs if necessary

INSERT @temp 
SELECT distinct [ID], '', '' from Test -- ADD '' for other ISOs if necessary

DECLARE c CURSOR read_only 
FOR SELECT [ID], [ISO], [Text] from test

DECLARE  @ID int, @ISO char(2), @Text varchar(255)
OPEN c

FETCH NEXT FROM c INTO @ID, @ISO, @Text
WHILE (@@fetch_status <> -1)
BEGIN
    IF (@@fetch_status <> -2)
    BEGIN
        UPDATE  @temp
        SET     [DE] = case when @ISO = 'DE' then @Text else [de] end,
            [EN] = case when @ISO = 'EN' then @Text else [en] end
                    -- add ISOs if necessary
        WHERE   [ID] = @ID
    END
    FETCH NEXT FROM c INTO @ID, @ISO, @Text
END

CLOSE c
DEALLOCATE c

SELECT * FROM @temp
于 2009-01-09T14:34:24.440 回答