0

我有以下数据表:

id displayName stringValue dateValue
59FAA56C-4C0C-456E-BA68-AC63250D6281 用户 SID SID-122 NULL
EBD6F18D-3CD3-4134-8FFB-7620D3EA93DF 用户 SID SID2 NULL
59FAA56C-4C0C-456E-BA68-AC63250D6281 用户名 我的用户 NULL
EBD6F18D-3CD3-4134-8FFB-7620D3EA93DF 用户名 用户 2 NULL
59FAA56C-4C0C-456E-BA68-AC63250D6281 上次登录 NULL 2012-01-01
EBD6F18D-3CD3-4134-8FFB-7620D3EA93DF 上次登录 NULL 2012-01-10

我想变成:

id [用户 SID] [用户名] [上次登录]
59FAA56C-4C0C-456E-BA68-AC63250D6281 SID-122 我的用户 2012-01-01
EBD6F18D-3CD3-4134-8FFB-7620D3EA93DF SID2 用户 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。关于如何让它正常工作的任何建议?

4

3 回答 3

4

你需要使用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 ║
╚══════════════════════════════════════╩══════════╩═══════════╩════════════╝

这是一个带有演示的 sqlfiddle 供您尝试。

于 2013-04-25T18:31:35.663 回答
3

您可以通过取消透视然后旋转数据来获取值。unpivot 过程会将stringValueanddateValue列转换为多行,然后您可以 PIVOTdisplayname列值:

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 |
于 2013-04-25T23:18:38.383 回答
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
于 2013-04-25T21:49:00.730 回答