MS Acess:合并并转置多个表

时间:2018-09-28 12:04:22

标签: sql ms-access

我有许多带有许多列的静态表。他们都有一个共同的专栏。我想对每个表进行转置,以使列名变为行,将列值变为行,以便有一个“公共”列。例如:

+---------+---+------+-----+---------+-----+
| 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字符串,因此会出现错误,提示查询过于复杂。看不到其他解决方法...

2 个答案:

答案 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