SQL表行到列 - 可能的PIVOT?

时间:2014-08-04 16:02:27

标签: sql sql-server pivot

我有一张Active Direcory的信息表,但不幸的是它显示的是这样的;

+------+------------+----------------+-------------------+
| dnId | propNameId |  propertyName  |   propertyValue   |
+------+------------+----------------+-------------------+
|    1 |         10 | objectsid      | S-1-5-32-548      |
|    1 |         19 | _objectclass   | group             |
|    1 |         80 | cn             | Account Operators |
|    1 |         82 | samaccountname | Account Operators |
|    1 |         85 | name           | Account Operators |
|    2 |         10 | objectsid      | S-1-5-32-544      |
|    2 |         19 | _objectclass   | group             |
|    2 |         80 | cn             | Administrators    |
|    2 |         82 | samaccountname | Administrators    |
|    2 |         85 | name           | Administrators    |
|    3 |         10 | objectsid      | S-1-5-32-551      |
|    3 |         19 | _objectclass   | group             |
|    3 |         80 | cn             | Backup Operators  |
|    3 |         82 | samaccountname | Backup Operators  |
|    3 |         85 | name           | Backup Operators  |
+------+------------+----------------+-------------------+

使用一堆临时表和连接,我可以让它显示我想要的,就像这样;

+------+--------------+--------------+-------------------+-------------------+-------------------+
| dnId |  objectsid   | _objectclass |        cn         |  samaccountname   |       name        |
+------+--------------+--------------+-------------------+-------------------+-------------------+
|    1 | S-1-5-32-548 | group        | Account Operators | Account Operators | Account Operators |
|    2 | S-1-5-32-544 | group        | Administrators    | Administrators    | Administrators    |
|    3 | S-1-5-32-551 | group        | Backup Operators  | Backup Operators  | Backup Operators  |
+------+--------------+--------------+-------------------+-------------------+-------------------+

但这感觉非常混乱和冗长。我确信必须有更优雅的方式来做这件事,也许使用 PIVOT ,我已经尝试过(并且失败了。

有任何想法/建议吗?

编辑:道歉,删除了mysql标签(这是自动建议的)。我正在使用MS SQL Server 2008 R2。

2 个答案:

答案 0 :(得分:5)

您没有指定正在使用的数据库,但以下内容适用于SQL Server或MySQL。您可以使用带有CASE表达式的聚合函数来创建新列名:

select
  dnid,
  max(case when propertyName = 'objectsid' then propertyValue end) objectsid,
  max(case when propertyName = '_objectclass ' then propertyValue end) objectclass ,
  max(case when propertyName = 'cn' then propertyValue end) cn,
  max(case when propertyName = 'samaccountname' then propertyValue end) samaccountname,
max(case when propertyName = 'name' then propertyValue end) name
from yourtable
group by dnid;

请参阅SQL Fiddle with Demo

答案 1 :(得分:3)

如果您正在使用SQL Server(不确定您的代码),此查询将使用PIVOT

生成您要查找的结果
SELECT p.*
FROM (
  SELECT dnId, propertyName, propertyValue FROM myTable
) AS t
PIVOT(
  MAX(propertyValue)
  FOR propertyName IN (objectsid, _objectclass, cn, samaccountname, name)
) AS p;

查看SQL Fiddle here