如何在sql中以行方式显示数据?

时间:2012-11-20 03:48:05

标签: sql sql-server sql-server-2008 pivot unpivot

Select * from Table1

输出

Alias(Auto generate no)   ShortName       LongName         IssuerID       TypeName
 1                         ABC           ABC Pvt Ltd.         23            Current
 2                         DEF           DEF Pvt Ltd.         34            Provisional
 3                         GHI           GHI Pvt Ltd.         50            Legacy

我想以行方式查看

预期产出

Fields        Current           Provisional      Legacy

Alias          1                   2              3
ShortName      ABC                DEF            GHI
LongName       ABC Pvt Ltd.      DEF Pvt Ltd.   GHI Pvt Ltd.
IssuerID       23                 34              50

如何针对上述情况进行选择查询?

我试过了:

select *
from Table1
pivot
(
   avg(IssuerID) for TypeName in
   (
      [Fields],[Current],[Provisional],[Legacy]
   )
) as TypeName

2 个答案:

答案 0 :(得分:1)

这种类型的数据转换可以通过在SQL Server中同时应用UNPIVOTPIVOT函数来完成。

UNPIVOT函数会使您的列AliasShortNameLongNameIssuerID将其转换为行值。但是,为了UNPIVOT工作,这些值的数据类型必须相同:

select typename, value, fields
from
(
  select cast(alias as varchar(20)) alias,
    shortname,
    longname,
    cast(issuerid as varchar(20)) issuerid,
    typename
  from Table1
) u
unpivot
(
  value
  for fields in (Alias, ShortName, LongName, IssuerId)
) unpiv

请参阅SQL Fiddle with Demo

数据UNPIVOT后,您可以将PIVOT函数应用于Typename列值:

select fields, [current], [provisional], [legacy]
from
(
  select typename, value, fields
  from
  (
    select cast(alias as varchar(20)) alias,
      shortname,
      longname,
      cast(issuerid as varchar(20)) issuerid,
      typename
    from Table1
  ) u
  unpivot
  (
    value
    for fields in (Alias, ShortName, LongName, IssuerId)
  ) unpiv
) src
pivot
(
  max(value)
  for typename in([current], [provisional], [legacy])
) piv

请参阅SQL Fiddle with Demo

查询结果为:

|    FIELDS |      CURRENT |  PROVISIONAL |       LEGACY |
----------------------------------------------------------
|     alias |            1 |            2 |            3 |
|  issuerid |           23 |           34 |           50 |
|  longname | ABC Pvt Ltd. | DEF Pvt Ltd. | GHI Pvt Ltd. |
| shortname |          ABC |          DEF |          GHI |

如果您无权访问UNPIVOTPIVOT函数,则可以使用UNION ALL查询复制UNPIVOT,然后使用聚合函数CASE复制PIVOT

select fields,
  max(case when typename = 'current' then value end) [current],
  max(case when typename = 'provisional' then value end) provisional,
  max(case when typename = 'legacy' then value end) legacy
from
(
  select typename, cast(alias as varchar(20)) value, 'alias' fields
  from Table1 
  union all
  select typename, shortname value, 'shortname' fields
  from Table1 
  union all
  select typename, longname value, 'longname' fields
  from Table1 
  union all
  select typename, cast(issuerid as varchar(20)) value, 'issuerid' fields
  from Table1 
) src
group by fields

请参阅SQL Fiddle with Demo

两个版本的结果都是一样的。

答案 1 :(得分:0)

您需要什么,并不简单,对PIVOT来说这不是一项好任务。

Here is a similiar question以及这种传播的可能解决方案。

首先,如果你检查想要的输出,你甚至必须“混合”列的类型。因此,为此,您必须将整数或其他数字列转换或转换为varchar类型。 (列只有一种类型)

对于PIVOT,您只能使用一个聚合。 有时它只是为了考虑如何欺骗它而烦恼,有时更简单但更长的解决方案可以更好地工作。

您可以尝试这样的代码:(这是一个显示它的SQL Fiddle demo。)

WITH CTE_DATA
AS (
  SELECT  DISTINCT
  CAST([Current].Alias as varchar(64)) AS Alias_Current,
  [Current].ShortName AS ShortName_Current,
  [Current].LongName AS LongName_Current,
  CAST([Current].IssuerID as varchar(64)) AS IssuerID_Current,
  CAST(Provisional.Alias as varchar(64)) AS Alias_Provisional,
  Provisional.ShortName AS ShortName_Provisional,
  Provisional.LongName AS LongName_Provisional,
  CAST(Provisional.IssuerID as varchar(64)) AS IssuerID_Provisional,
  CAST(Legacy.Alias as varchar(64)) AS Alias_Legacy,
  Legacy.ShortName AS ShortName_Legacy,
  Legacy.LongName AS LongName_Legacy,
  CAST(Legacy.IssuerID as varchar(64)) AS IssuerID_Legacy
  FROM 
  (SELECT * FROM Data WHERE TypeName = 'Current') As [Current]
  CROSS JOIN (SELECT * FROM Data WHERE TypeName = 'Provisional') As Provisional
  CROSS JOIN (SELECT * FROM Data WHERE TypeName = 'Legacy') AS Legacy
  )
SELECT 'Alias' AS Fields, Alias_Current AS [Current], 
Alias_Provisional AS Provisional, Alias_Legacy AS Legacy
    FROM CTE_DATA
    UNION ALL
SELECT 'ShortName' AS Fields, ShortName_Current AS [Current], 
ShortName_Provisional AS Provisional, ShortName_Legacy AS Legacy
    FROM CTE_DATA
    UNION ALL
SELECT 'LongName' AS Fields, LongName_Current AS [Current], 
LongName_Provisional AS Provisional, LongName_Legacy AS Legacy
    FROM CTE_DATA
    UNION ALL
SELECT 'IssuerID' AS Fields, IssuerID_Current AS [Current], 
IssuerID_Provisional AS Provisional, IssuerID_Legacy AS Legacy
    FROM CTE_DATA