Ms Access Query:通过查询连接行

Posted

技术标签:

【中文标题】Ms Access Query:通过查询连接行【英文标题】:Ms Access Query: Concatenating Rows through a query 【发布时间】:2011-07-27 21:31:36 【问题描述】:

假设我在 Ms Access 中有一个包含以下信息的表:

ColumnA ColumnB
1       abc
1       pqr
1       xyz
2       efg
2       hij
3       asd

我的问题是,如何将第二列中的值连接到基于第一列的行值。我想要的查询结果如下:

ColumnA ColumnB
1       abc, pqr, xyz
2       efg, hij
3       asd

我想通过查询来实现这一点。有人可以帮我实现吗?

【问题讨论】:

1) 标准 SQL 没有 Concat 设置函数:结果数据类型是什么?它会违反1NF吗?会是一套吗?怎么能查询到这样的数据?等等; 2)Access2007引入了多值类型(theregister.co.uk/2006/07/18/multivalued_datatypes_access/…); 3) 你考虑过报告吗? Access 附带的那个非常好。 【参考方案1】:

你需要一个函数来进行连接。

Microsoft Access condense multiple lines in a table

使用您的数据的示例:

Select T.ColumnA
  , GetList("Select ColumnB From Table1 As T1 Where T1.ColumnA = " & [T].[ColumnA],"",", ") AS ColumnBItems
From Table1 AS T
Group By T.ColumnA;

【讨论】:

我需要在查询而不是 vba 函数中实现这一点。我已经在我的问题中说明了这一点。 阅读该链接。您将创建一个函数并在查询中使用该函数。否则没有办法做到这一点。 但是难道不是只能在查询中做吗? @reggie - 不。无法使用动态数量的子项来做到这一点。 我正在尝试您的解决方案。但它没有给我任何结果。【参考方案2】:

这里有一个出色的链接:如何通过调用函数从 SQL 中执行此操作。说明非常清晰,功能是为您编写的,因此您只需复制、粘贴和执行即可。即使是不了解VB的人也可以轻松实现它: Concatenate values from related records

【讨论】:

【参考方案3】:

这可能很难获得。如果您必须在查询而不是函数中执行此操作,那么您将遇到的问题是您可以连接到一列中的行数的限制。到目前为止,我发现实现这一目标的唯一方法是通过 iif 语句。

SELECT 
test1.ColumnA AS ColumnA, 
First([test1].[ColumnB]) & IIf(Count([test1].[ColumnB])>1,"," & Last([test1].[ColumnB])) AS ColumnB
FROM test1
GROUP BY test1.ColumnA;

返回:

ColumnA  ColumnB 
1      abc,xyz 
2      efg,hij 
3      asd

这将只返回第一个和最后一个,但我相信你可以通过一些工作来计算选择函数,但就像我说的你必须为每个要添加的附加项目添加更多 iif 语句,因此有限制。

【讨论】:

是的。如果您能为我发布该解决方案,我将不胜感激。 @reggie - 上述解决方案的问题是子项的数量未知。现在,每个项只有 2 个 B 列值。当有 10 个时会发生什么? 100? 最终..它取决于您计划拥有多少项目...如果 columnA 值可以在 columnB 中分组 20 个项目...这可能不是您的最佳解决方案...如果您正在寻找在 2 - 3 它可能。 @Thomas.. 因此存在限制。在实践中,我有第三项,如果计数超过两个,它会显示“更多...”,但这一切都取决于 OP 的需求和要求。如果他由于某种原因不能使用某个功能……他不能使用一个功能……而且如上所述……如果他有超过 3 或 4 个,这不是一个好的解决方案。 @Patrick - 同意。不是贬低您的解决方案,而是 OP 要求的方法。【参考方案4】:

表可以有一个序列列,这给它一个唯一的 ColumnA-sequence 主键:

table: t1
ColumnA sequence ColumnB
1       1        abc
1       2        pqr
1       3        xyz
2       1        efg
2       2        hij
3       1        asd

并且可以创建一个交叉表:

query: x1
TRANSFORM Min([columnB] & ", ") AS Expr1
SELECT t1.columnA
FROM t1
GROUP BY t1.columnA
PIVOT t1.sequence;

columnA 1    2    3
1       abc, pqr, xyz,
2       efg, hij,
3       asd,

那么最后一个查询可以合并列并去掉最后一个逗号:

SELECT x1.columnA, Left([1] & [2] & [3],Len([1] & [2] & [3])-2) AS columnB FROM x1;

columnA columnB
1       abc, pqr, xyz
2       efg, hij
3       asd

要自动填充序列,可以使用以下 VBA 代码:

Sub fill_sequence_t1()
  Dim i: i = 1
  Do While DCount("*", "t1", "sequence IS NULL") > 0
    DoCmd.RunSQL "SELECT t1.columnA, Min(t1.columnB) AS columnB_min INTO t2" & _
                 " FROM t1 WHERE t1.sequence IS NULL GROUP BY t1.columnA;"
    DoCmd.RunSQL "UPDATE t1 INNER JOIN t2 ON (t1.columnA = t2.columnA)" & _
                 " AND (t1.columnB = t2.columnB_min) SET t1.sequence=" & i
    CurrentDb.TableDefs.Delete "t2"
    i = i + 1
  Loop
End Sub

【讨论】:

以上是关于Ms Access Query:通过查询连接行的主要内容,如果未能解决你的问题,请参考以下文章

如何通过 Python 3.5.1 创建永久 MS Access Query?

基于筛选查询的MS Access查询

谁能帮我将 Access Query 转换为 MS SQL Query

使用 MS Access Union Query 合并 3 个表/查询

左连接 SQL 查询 - MS Access

具有用户功能条件的 MS Access 查询停止处理 odbc 数据