【问题标题】:Concatenation in between records in Access QueryAccess Query 中记录之间的连接
【发布时间】:2017-03-29 20:09:03
【问题描述】:

我在 Access 中有一个表格,其中列出了属性 ID 和每个获得认证的年份:

B_ID    CertYear
a   2016
b   2016
c   2015
a   2015
a   2014

我想创建一个查询/表来计算每座建筑物已获得认证的年数,并在单独的列中列出每年,如下所示:

B_ID    Count_CertYear  Detail_CertYear
a   3   2016|2015|2014
b   1   2016
c   1   2015

在查询设计中,我能够计算前两列,但无法弄清楚如何计算第三列。这是我目前的表格布局方式。

Field:  B_ID    B_ID
Table:  MyTable MyTable
Total:  Count   Count
Sort:       
Show:       
Criteria:       
Or:     

【问题讨论】:

    标签: ms-access concatenation


    【解决方案1】:

    Access 确实带有一组域聚合函数,Count()、Sum()、Avg()、First()、Last()、Min()、Max()、StDev()、StDevP()、然而,Var() 和 VarP() 没有本地域连接函数。

    我的偏好是在 SQL Server 中处理此问题并通过存储过程返回结果,但如果您仅限于 Access,那么最好使用 Patrick Matthews 的域连接函数here

    来自 DConcat() 的文档:

    SELECT DConcat("Account","Sample") AS Accounts
    FROM Sample
    GROUP BY DConcat("Account","Sample");
    
    Returns:
    Accounts
    -----------------------------------------------------------------------------
    Acct1, Acct10, Acct2, Acct3, Acct4, Acct5, Acct6, Acct7, Acct8, Acct9
    

    对于您问题中的具体示例:

    SELECT B_ID
         , COUNT(Cert_Year)
         , DConcat("CertYear","MyTable", "B_ID='" & [B_ID] & "'") AS Detail_CertYear
    FROM MyTable
    GROUP BY B_ID
    

    应该返回这些值:

    B_ID Count_CertYear Detail_CertYear
    ------------------------------
    a    3              2016,2015,2014
    b    1              2016
    c    1              2015
    

    【讨论】:

    • 从查询设计或表达式生成器的 SQL 视图中的 Access 无法识别函数 Dconcat。有什么选择吗?
    【解决方案2】:

    要在 Access 中执行此操作,您可以使用交叉表查询,或使用函数根据 B_ID 连接年份。

    您说您想“将每年的列表分别列在不同的列中”,所以我认为交叉表在这里更适合您。

    这里是交叉表 SQL:

    TRANSFORM Min(t.[CertYear]) AS MinOfCertYear
    SELECT t.[B_ID], Count(t.[CertYear]) AS [TotalYears]
    FROM (
      SELECT 
        t1.B_ID, 
        t1.CertYear, 
        COUNT(t2.ID) AS YearCount
      FROM YourTable t1
      INNER JOIN YourTable t2
              ON t1.B_ID = t2.B_ID
             AND t1.ID <= t2.ID
      GROUP BY t1.B_ID, t1.CertYear
    ) t
    GROUP BY t.[B_ID]
    PIVOT 'Year: ' & t.[YearCount];
    

    如果您只想在逗号分隔的单列中返回年份,则可以将找到的函数 here 用作常规聚合查询的一部分。

    那么,您的 SQL 将是:

    SELECT 
      t1.B_ID, 
      COUNT(t1.ID) AS YearCount, 
      SimpleCSV("SELECT t3.CertYear FROM YourTable t3 WHERE t3.B_ID = '" & t1.B_ID & "'") AS [Years]
    FROM YourTable t1
    GROUP BY t1.B_ID
    

    【讨论】:

    • @David Marten,我将第二个示例中的 SQL 插入到查询设计中的 SQL 视图中。我收到一条错误消息,指出 SimpleCSV 是一个未定义的函数。此外,我试图创建的表中的所有数据都来自一个表。目前尚不清楚“t3”来自何处。能详细点吗?
    • SimpleCSV() 是我在答案中发布的链接中的用户定义 VBA 函数。将其保存在新的标准 VBA 模块中(将模块命名为“SimpleCSV”以外的任何名称)。编译代码(VBA 编辑器中的调试菜单 -> 编译) t3 只是一个别名 - 该函数通过为聚合查询中的每条记录打开一个单独的记录集并连接具有相同 B_ID 的记录来工作。我是想和你核实一下你的表有一个主键字段吗?此外,请确保将出现的“YourTable”替换为您的实际表名。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-11-23
    • 2013-03-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多