Sql 将行值转换为列

Sql 将行值转换为列,sql,ms-access,ms-access-2007,pivot,ms-access-2010,Sql,Ms Access,Ms Access 2007,Pivot,Ms Access 2010,我有下表: Name Group John 2A John 1B Barry 2A Ron 1B Ron 2A Ron 2C 我正在尝试创建一个查询,将组列分隔为每个实例的新列 预期结果 Name Group1 Group2 Group3 John 2A 1B Barry 2A Ron 1B

我有下表:

Name        Group
John        2A
John        1B
Barry       2A
Ron         1B
Ron         2A
Ron         2C
我正在尝试创建一个查询,将组列分隔为每个实例的新列

预期结果

Name        Group1      Group2      Group3
John        2A          1B
Barry       2A
Ron         1B          2A          2C
在本例中,我知道最大组数为3。所以我制作了Group1、Group2和Group3列


有点像交叉表,但我不能使用交叉表,因为值选项必须是数字,并且我有字符串。至少在我正在使用的MS Access中没有。

不幸的是,MS Access没有一个行号函数来轻松地为每个名称的每个项目分配一个值。我会用下面的方法得到结果

首先,通过使用下面的查询,您将返回姓名、组和为每个组每人分配的递增数字:

select name, 
  group, 
  (select count(*) 
   from yourtable t1 
   where yourtable.name = t1.name
     and yourtable.group<= t1.group) AS rw
from yourtable;
然后可以使用函数和最大聚合函数将值从行转换为列:

SELECT name,
  max(iif(rw=1, group, null)) as Group1,
  max(iif(rw=2, group, null)) as Group2,
  max(iif(rw=3, group, null)) as Group3
FROM 
(
  select name, 
    group, 
    (select count(*) 
        from yourtable t1 
        where yourtable.name = t1.name 
            and yourtable.group<= t1.group) AS rw
  from yourtable
) d
group by name
order by name;
编辑:表中的数据不是固有的顺序,但如果您有一列使用id等按您想要的顺序放置数据,那么您应该能够将查询更改为以下内容:

SELECT name, 
    max(iif(rw=1, group, null)) AS Group1, 
    max(iif(rw=2, group, null)) AS Group2,
    max(iif(rw=3, group, null)) AS Group3
FROM 
(
    SELECT name, 
      group, 
      (select count(*) 
       from table9 t1
       where yourtable.name = t1.name 
         and t1.id<= yourtable.id
        )  as rw
    from yourtable
) AS d
GROUP BY name
ORDER BY name;

你为什么不期望这些组在同一列中呢?2A在第2组,1B在第1组等等?对于Ron来说,什么决定哪一个值进入第1组?不清楚为什么用“1B”代替“2A”或“2C”。我注意到在第一个查询中顺序发生了变化。@Rick我不确定我是否理解您的评论。您希望数据的顺序是什么?我运行了第一个查询,rw coulnm给出了组号,但顺序不正确。我甚至尝试添加一个自动编号字段,并在子查询中包含order by id asc。@Rick您希望数据的顺序是什么?我希望Group1从上到下位于列表的第一位,然后Group2第二位,Group3第三位。例如,对于ron,我得到了:Group1:1B、Group2:2C、Group3:2A
+-------+--------+--------+--------+
|  name | Group1 | Group2 | Group3 |
+-------+--------+--------+--------+
| Barry | 2A     |        |        |
| John  | 2A     | 1B     |        |
| Ron   | 2C     | 2A     | 1B     |
+-------+--------+--------+--------+
SELECT name, 
    max(iif(rw=1, group, null)) AS Group1, 
    max(iif(rw=2, group, null)) AS Group2,
    max(iif(rw=3, group, null)) AS Group3
FROM 
(
    SELECT name, 
      group, 
      (select count(*) 
       from table9 t1
       where yourtable.name = t1.name 
         and t1.id<= yourtable.id
        )  as rw
    from yourtable
) AS d
GROUP BY name
ORDER BY name;
+-------+--------+--------+--------+
|  name | Group1 | Group2 | Group3 |
+-------+--------+--------+--------+
| Barry | 2A     |        |        |
| John  | 2A     | 1B     |        |
| Ron   | 1B     | 2A     | 2C     |
+-------+--------+--------+--------+