我有许多带有许多列的静态表。他们都有一个共同的专栏。我想对每个表进行转置,以使列名变为行,将列值变为行,以便有一个“公共”列。例如:
+---------+---+------+-----+---------+-----+
| Table 1 | | x1 | x2 | x3 | x4 |
+---------+---+------+-----+---------+-----+
| | 1 | 5 | 4 | alpha | 6 |
| | 2 | 5 | 1 | alpha | 5 |
| | 3 | 8 | 4 | alpha | 6 |
| | 4 | 0 | 8 | Beta | 1 |
| | 5 | 10 | 3 | Beta | 5 |
| | 6 | 3 | 6 | Beta | 4 |
| | … | … | … | … | … |
+---------+---+------+-----+---------+-----+
+---------+---+-----+-----+---------+
| Table 2 | | y1 | y2 | x3 |
+---------+---+-----+-----+---------+
| | 1 | 2 | 7 | Alpha |
| | 2 | 1 | 4 | Beta |
| | … | … | … | … |
+---------+---+-----+-----+---------+
+--------------+----+---------+------------+--------------+--------------+
| RESULT TABLE | | x3 | Field Name | Column Value | Source Table |
+--------------+----+---------+------------+--------------+--------------+
| | 1 | Alpha | x1 | 5 | Table 1 |
| | 2 | Alpha | x2 | 4 | Table 1 |
| | 3 | Alpha | x4 | 6 | Table 1 |
| | 4 | Alpha | x1 | 5 | Table 1 |
| | 5 | Alpha | x2 | 1 | Table 1 |
| | 6 | Alpha | x4 | 5 | Table 1 |
| | 7 | Alpha | x1 | 8 | Table 1 |
| | 8 | Alpha | x2 | 4 | Table 1 |
| | 9 | Alpha | x4 | 6 | Table 1 |
| | 10 | Beta | x1 | 0 | Table 1 |
| | 11 | Beta | x2 | 8 | Table 1 |
| | 12 | Beta | x4 | 1 | Table 1 |
| | 13 | Beta | x1 | 10 | Table 1 |
| | 14 | Beta | x2 | 3 | Table 1 |
| | 15 | Beta | x4 | 5 | Table 1 |
| | 16 | Beta | x1 | 3 | Table 1 |
| | 17 | Beta | x2 | 6 | Table 1 |
| | 18 | Beta | x4 | 4 | Table 1 |
| | 19 | Alpha | y1 | 2 | Table 2 |
| | 20 | Alpha | y2 | 7 | Table 2 |
| | 21 | Beta | y1 | 1 | Table 2 |
| | 22 | Beta | y2 | 4 | Table 2 |
| | … | … | … | … | … |
+--------------+----+---------+------------+--------------+--------------+
在上面的示例中,x3是我要保留的公共列。所有其他列都变成具有各自值的行。
在Access SQL中这完全有可能吗?我是一个新手,无法找到解决方案,因为我需要首先将两个包合并,然后以某种方式将其旋转(除了x3列)。
以上只是一个示例,实际上每个表可以有很多列,所以我想尝试对任意数量的列进行动态
编辑:
我想出了一个动态解决方案。我可以使用VBA创建查询:
select x3 as x3, x1 as [field name], [x1] as [column value], 'Table 1' as [Source Table]
UNION ALL
select x3 as x3, x2 as [field name], [x2] as [column value], 'Table 1' as [Source Table]
...
这将获得正确格式的第一个表。
然后我可以对第二个表重复并进行合并以得到结果。
但是实际上,我的表包含很多列,因此该查询字符串很快变得非常大,不幸的是,Microsoft Access无法处理长的SQL字符串,因此会出现错误,提示查询过于复杂。看不到其他解决方法...
答案 0 :(得分:0)
使用apply
取消透视和union all
:
select v.x3, v.col, v.val, v.table
from t1 cross apply
(values ('table1', 'x1', x1, x3),
('table1', 'x2', x2, x3),
. . .
) v(table, col, val)
union all
select v.x3, v.col, v.val, v.table
from t2 cross apply
(values ('table2', 'x1', x1, x3),
('table2', 'x2', x2, x3),
. . .
) v(table, col, val)
. . .
请注意,要使此(或任何其他方法)正常工作,列的类型必须兼容。您可能需要将其转换为字符串才能使用。
答案 1 :(得分:0)
首先,您必须取消旋转两个表
/*UNPIVOT TABLE 1*/
SELECT ID
,X3
,FIELD_NAME
,COLUMN_VALUE
,SOURCE_TABLE = 'TABLE 1'
INTO ##TB1
FROM
(SELECT ID,X1,X2,X3,X4
FROM TABLE_1) AS P
UNPIVOT (COLUMN_VALUE
FOR FIELD_NAME IN (X1 , X2, X4)
) AS UNPVT
/*UNPIVOT TABLE 2*/
SELECT ID
,X3
,FIELD_NAME
,COLUMN_VALUE
,SOURCE_TABLE = 'TABLE 2'
INTO ##TB2
FROM
(SELECT ID,Y1,Y2,X3
FROM TABLE_2) AS P
UNPIVOT (COLUMN_VALUE
FOR FIELD_NAME IN (Y1,Y2)
) AS UNPVT
然后在两个上都使用Union
/*DISTINCT UNION BOTH TABLES*/
SELECT *
FROM ##TB2
UNION
SELECT *
FROM ##TB1
如果您要检查Microsoft Pivot and unpivot
如果您想提高性能,并且知道联接上没有重复的结果,我建议您使用UNION ALL Union