MS ACCESS 群组查询
MS ACCESS Group Query
这个真让我摸不着头脑。它有点像 GROUP_CONCAT,但有所不同。我很确定仅使用 SQL 无法做到这一点。我有一个在规范化 table 上执行 flip-table 的查询。结果如下所示:
|_Category_|_FieldA_|_FieldB_|_FieldC_|
|----------|--------|--------|--------|
| CAT1 | A | | |
|----------|--------|--------|--------|
| CAT1 | | B | |
|----------|--------|--------|--------|
| CAT1 | | | C |
|----------|--------|--------|--------|
| CAT1 | D | | |
|----------|--------|--------|--------|
| CAT1 | | | E |
|----------|--------|--------|--------|
| CAT1 | F | | |
|----------|--------|--------|--------|
我的挑战是将它压缩成尽可能少的行,但每个单元格只有一个值。
|_Category_|_FieldA_|_FieldB_|_FieldC_|
|----------|--------|--------|--------|
| CAT1 | A | B | C |
|----------|--------|--------|--------|
| CAT1 | D | | E |
|----------|--------|--------|--------|
| CAT1 | F | | |
|----------|--------|--------|--------|
有什么想法吗?
提前致谢。
马克
我遇到了同样的问题。看看:Microsoft Access condense multiple lines in a table
或在此处获取云版本https://www.apponfly.com/en/application/microsoft-access-2013
效果不错
正如我在对问题的评论中提到的,规范化的 table 应该如下所示:
|_Category_|_F_Name_|_F_Val__|
|----------|--------|--------|
| CAT1 | FieldA | A |
|----------|--------|--------|
| CAT1 | FieldB | B |
|----------|--------|--------|
| CAT1 | FieldC | C |
|----------|--------|--------|
| CAT1 | FieldB | D |
|----------|--------|--------|
| CAT1 | FieldC | E |
|----------|--------|--------|
| CAT1 | FieldA | F |
|----------|--------|--------|
如何实现?
SELECT A.Category, "FieldA" AS FieldName, A.FieldA AS FieldValue
FROM TableA AS A
WHERE NOT A.FieldA IS NULL
UNION ALL
SELECT A.Category, "FieldB", A.FieldB
FROM TableA AS A
WHERE NOT A.FieldB IS NULL
UNION ALL
SELECT A.Category, "FieldC", A.FieldC
FROM TableA AS A
WHERE NOT A.FieldC IS NULL;
要将数据导出到新的 table,请使用查询:
SELECT B.* INTO TableB
FROM (
--above query
) AS B;
不要忘记将自动编号字段(作为主键)添加到 TableB 以便能够识别每条记录。
据我了解,您想要旋转数据。没那么简单,因为我们需要模拟
ROW_NUMBER() OVER(PARTITION BY FieldName, ORDER BY ID)
MS Access 不支持。如何解决它?
SELECT B.ID, B.Category, B.FieldName, B.FieldValue,
(SELECT COUNT(A.FieldName)
FROM TableB AS A
WHERE A.FieldName=B.FieldName AND A.ID >=B.ID
GROUP BY A.FieldName ) AS TRank
FROM TableB AS B;
它应该产生以下记录集:
ID Category FieldName FieldValue TRank
1 CAT1 FieldA A 3
2 CAT1 FieldA D 2
3 CAT1 FieldA F 1
4 CAT1 FieldB B 1
5 CAT1 FieldC C 2
6 CAT1 FieldC E 1
但是...您不能将上述查询用作数据透视表的来源,因为“Microsoft Access 数据库引擎无法识别为有效的字段名称或表达式。(错误 3070 )”错误信息。所以,最后,您应该将这些数据导出到另一个 table(比方说 TableC)。
SELECT C.* INSERT INTO TableC
FROM TableB AS C
现在,您可以旋转数据:
TRANSFORM First(A.FieldValue) AS FirstOfFieldValue
SELECT A.Category, A.TRank
FROM TableC AS A
GROUP BY A.Category, A.TRank
PIVOT A.FieldName;
结果:
Category TRank FieldA FieldB FieldC
CAT1 1 F B E
CAT1 2 D C
CAT1 3 A
干杯,
马切伊
这个真让我摸不着头脑。它有点像 GROUP_CONCAT,但有所不同。我很确定仅使用 SQL 无法做到这一点。我有一个在规范化 table 上执行 flip-table 的查询。结果如下所示:
|_Category_|_FieldA_|_FieldB_|_FieldC_|
|----------|--------|--------|--------|
| CAT1 | A | | |
|----------|--------|--------|--------|
| CAT1 | | B | |
|----------|--------|--------|--------|
| CAT1 | | | C |
|----------|--------|--------|--------|
| CAT1 | D | | |
|----------|--------|--------|--------|
| CAT1 | | | E |
|----------|--------|--------|--------|
| CAT1 | F | | |
|----------|--------|--------|--------|
我的挑战是将它压缩成尽可能少的行,但每个单元格只有一个值。
|_Category_|_FieldA_|_FieldB_|_FieldC_|
|----------|--------|--------|--------|
| CAT1 | A | B | C |
|----------|--------|--------|--------|
| CAT1 | D | | E |
|----------|--------|--------|--------|
| CAT1 | F | | |
|----------|--------|--------|--------|
有什么想法吗?
提前致谢。
马克
我遇到了同样的问题。看看:Microsoft Access condense multiple lines in a table
或在此处获取云版本https://www.apponfly.com/en/application/microsoft-access-2013
效果不错
正如我在对问题的评论中提到的,规范化的 table 应该如下所示:
|_Category_|_F_Name_|_F_Val__|
|----------|--------|--------|
| CAT1 | FieldA | A |
|----------|--------|--------|
| CAT1 | FieldB | B |
|----------|--------|--------|
| CAT1 | FieldC | C |
|----------|--------|--------|
| CAT1 | FieldB | D |
|----------|--------|--------|
| CAT1 | FieldC | E |
|----------|--------|--------|
| CAT1 | FieldA | F |
|----------|--------|--------|
如何实现?
SELECT A.Category, "FieldA" AS FieldName, A.FieldA AS FieldValue
FROM TableA AS A
WHERE NOT A.FieldA IS NULL
UNION ALL
SELECT A.Category, "FieldB", A.FieldB
FROM TableA AS A
WHERE NOT A.FieldB IS NULL
UNION ALL
SELECT A.Category, "FieldC", A.FieldC
FROM TableA AS A
WHERE NOT A.FieldC IS NULL;
要将数据导出到新的 table,请使用查询:
SELECT B.* INTO TableB
FROM (
--above query
) AS B;
不要忘记将自动编号字段(作为主键)添加到 TableB 以便能够识别每条记录。
据我了解,您想要旋转数据。没那么简单,因为我们需要模拟
ROW_NUMBER() OVER(PARTITION BY FieldName, ORDER BY ID)
MS Access 不支持。如何解决它?
SELECT B.ID, B.Category, B.FieldName, B.FieldValue,
(SELECT COUNT(A.FieldName)
FROM TableB AS A
WHERE A.FieldName=B.FieldName AND A.ID >=B.ID
GROUP BY A.FieldName ) AS TRank
FROM TableB AS B;
它应该产生以下记录集:
ID Category FieldName FieldValue TRank
1 CAT1 FieldA A 3
2 CAT1 FieldA D 2
3 CAT1 FieldA F 1
4 CAT1 FieldB B 1
5 CAT1 FieldC C 2
6 CAT1 FieldC E 1
但是...您不能将上述查询用作数据透视表的来源,因为“Microsoft Access 数据库引擎无法识别为有效的字段名称或表达式。(错误 3070 )”错误信息。所以,最后,您应该将这些数据导出到另一个 table(比方说 TableC)。
SELECT C.* INSERT INTO TableC
FROM TableB AS C
现在,您可以旋转数据:
TRANSFORM First(A.FieldValue) AS FirstOfFieldValue
SELECT A.Category, A.TRank
FROM TableC AS A
GROUP BY A.Category, A.TRank
PIVOT A.FieldName;
结果:
Category TRank FieldA FieldB FieldC
CAT1 1 F B E
CAT1 2 D C
CAT1 3 A
干杯,
马切伊