透视情况何时?

时间:2013-04-25 17:47:25

标签: sql sql-server-2008 pivot

我有以下数据表:

id                                      displayName stringValue     dateValue
59FAA56C-4C0C-456E-BA68-AC63250D6281    User SID    SID-122         NULL
EBD6F18D-3CD3-4134-8FFB-7620D3EA93DF    User SID    SID2            NULL
59FAA56C-4C0C-456E-BA68-AC63250D6281    User Name   My User         NULL
EBD6F18D-3CD3-4134-8FFB-7620D3EA93DF    User Name   User 2          NULL
59FAA56C-4C0C-456E-BA68-AC63250D6281    Last Login  NULL            2012-01-01
EBD6F18D-3CD3-4134-8FFB-7620D3EA93DF    Last Login  NULL            2012-01-10

我想变成:

id                                      [User SID]  [User Name] [Last Login]
59FAA56C-4C0C-456E-BA68-AC63250D6281    SID-122     My User     2012-01-01
EBD6F18D-3CD3-4134-8FFB-7620D3EA93DF    SID2        User 2      2012-01-10

我可以使用以下支点部分工作:

SELECT id, [User SID], [User Name], [Last Login] from 
            (
                select id
                    , stringValue
                    , displayName
                from #TestTable
           ) x
            pivot 
            (
                 MAX(stringValue)
                for displayName in ([User SID], [User Name], [Last Login])
            ) p 

除了lastLogin填充NULL(这是有意义的,因为它不包含在任何地方的MAX中)。

现在,我尝试将枢轴更改为:

            pivot 
            (
                 MAX(ISNULL(stringValue,dateValue))
                for displayName in ([User SID], [User Name], [Last Login])
            ) p 

还有:

            pivot 
            (
                 MAX(CASE WHEN stringValue IS NULL THEN dateValue ELSE stringValue END)
                for displayName in ([User SID], [User Name], [Last Login])
            ) p 

但这些都不是有效的sql。关于如何使其正常工作的任何建议?

3 个答案:

答案 0 :(得分:3)

您是否需要使用PIVOT ?,因为一种简单的方法是使用CASE表达式:

SELECT  id,
        MIN(CASE WHEN displayName = 'User SID' THEN stringValue END) [User SID],
        MIN(CASE WHEN displayName = 'User Name' THEN stringValue END) [User Name],
        MIN(CASE WHEN displayName = 'Last Login' THEN dateValue END) [Last Login]
FROM YourTable
GROUP BY id

结果如下:

╔══════════════════════════════════════╦══════════╦═══════════╦════════════╗
║                  ID                  ║ USER SID ║ USER NAME ║ LAST LOGIN ║
╠══════════════════════════════════════╬══════════╬═══════════╬════════════╣
║ EBD6F18D-3CD3-4134-8FFB-7620D3EA93DF ║ SID2     ║ User 2    ║ 2012-01-10 ║
║ 59FAA56C-4C0C-456E-BA68-AC63250D6281 ║ SID-122  ║ My User   ║ 2012-01-01 ║
╚══════════════════════════════════════╩══════════╩═══════════╩════════════╝

And here is a sqlfiddle有一个演示供您试用。

答案 1 :(得分:3)

您可以通过取消隐藏然后旋转数据来获取值。 unpivot进程会将stringValuedateValue列转换为多行,然后您可以隐藏displayname列值:

select id, [User SID], [User Name], [Last Login]
from
(
  select t.id,
    t.displayname,
    c.value
  from yourtable t
  cross apply
  (
    values
      ('stringvalue', stringvalue),
      ('datevalue', convert(varchar(10), datevalue, 120))
  ) c (col, value)
) src
pivot
(
  max(value)
  for displayname in ([User SID], [User Name], [Last Login])
) piv;

请参阅SQL Fiddle with Demo

结果是:

|                                   ID | USER SID | USER NAME | LAST LOGIN |
----------------------------------------------------------------------------
| EBD6F18D-3CD3-4134-8FFB-7620D3EA93DF |     SID2 |    User 2 | 2012-01-10 |
| 59FAA56C-4C0C-456E-BA68-AC63250D6281 |  SID-122 |   My User | 2012-01-01 |

答案 2 :(得分:2)

从数据的外观来看,除非你还做了一些我们没有看过的计算,你甚至不需要使用聚合函数,更不用说PIVOT了。

我会做这样的事情:

 WITH UserSID
 AS (
    SELECT ID
        ,  [User SID] = stringValue
    FROM   [your table]
    WHERE  displayName = 'User SID'
 )
 ,  UserName
 AS (
    SELECT ID
       ,   [User Name] = stringValue
    FROM   [your table]
    WHERE  displayName = 'User name'
 )
 ,  LastLogin
 AS (
    SELECT ID
       ,   [Last Login] = dateValue
    FROM   [your table]
    WHERE  displayName = 'Last Login'
)
SELECT  us.ID
   ,    us.[User SID]  
   ,    un.[User Name]
   ,    ll.[Last Login]
FROM    UserSID us
    JOIN UserName un
       ON us.ID = un.ID
    JOIN LastLogin ll
       ON us.ID = ll.ID
ORDER BY
       us.ID