【问题标题】:Ms Access Rank and match two querysMs Access Rank 并匹配两个查询
【发布时间】:2012-05-07 12:36:51
【问题描述】:

我已经被这个问题困扰了一段时间,但还不能解决。这里是:

我的 Acces 数据库中有一些表和一些查询。我有一个查询来选择一些字段并按它们的频率排序。这是为两张桌子完成的,给了我两个等级。看起来像这样(并且按 DESC 排序,因此频率较高的在顶部):

表 1 表 2 值 1 频率 1 值 2 频率 2

Table2.Value2 是 Table1.Value1 的子集,所以我想匹配 Value2 和 Value1 加上在 Table2 上显示 Value2 位置(排名)的列,所以我可以比较它在 Table1 和 Table2 排名上的位置。所以我'会有类似的东西:

表3 值 1 频率 1 频率 2 位置表 2

我已经搜索了如何返回字段的行号(无法让它工作),我可以将两个表放在一起并按值匹配,但无法得到我需要的结果。

我的SQL知识有限,根本不懂VB,请多多关照:) 提前致谢

编辑 示例:

表 1 表 2 姓名 频率 姓名 频率 玛丽 5 保罗 2 约翰福音 4 约翰福音 1 保罗 3

我想要的输出:

表3 名称 频率 Frequency2 RankIn2 Mary 5 //没有出现在table2中,freq=null rankin2=null John 4 1 2 //table2 的第二行 Paul 3 2 1 //table2 的第一行

【问题讨论】:

  • 您是否有两个表格的示例以及您想要的结果。
  • 什么决定了表3中的排名?
  • 您没有在 Table1 中显示排名。您有一个按降序排列的频率。您希望 RankIn2 根据该值自动递增吗?
  • 嗯,没有明确的排名,但降序创建一个。我认为它必须类似于找出 Table2 中 Name 的行号才能放入列中。我将编辑示例,也许它会更清楚。

标签: sql ms-access match rank


【解决方案1】:

我会使用 VBA,因为 Access 的有限 SQL 不能很好地理解排名概念。步骤如下。

  1. 为 Table2 创建第三个字段并将其命名为 Rank。

  2. 通过按 Alt+F11、Insert->Module 并在打开的编辑器窗口中粘贴以下代码来创建以下子例程。

    Public Sub RankTable()

    Dim rs As Recordset, iRank As Integer, strQuery As String
    
    strQuery = "SELECT * FROM Table2 ORDER BY Freq DESC"
    
    Set rs = CurrentDb.OpenRecordset(strQuery, dbOpenDynaset)
    
    rs.MoveFirst
    iRank = 1
    
    Do
    
        rs.Edit
        rs.Fields(3) = iRank
        rs.Update
    
        rs.MoveNext
        iRank = iRank + 1
    
    Loop While Not rs.EOF
    
    rs.Close
    

    结束子

  3. 运行上述子例程。 (请记住,每次 Table2 有更新时,您都必须运行它。)

  4. 创建查询

    SELECT Table1.Name, Table1.Frequency, Table2.Frequency AS Frequency2, Table2.Rank 从表 1 LEFT OUTER JOIN Name ON Table1.Name = Table2.Name ORDER BY Table2.频率

【讨论】:

  • 我的代码格式不正确,不知道为什么。对此感到抱歉。
  • 如我所说,我根本不懂VB。我应该把“Sub RankTable”和“EndSub”这行去掉吗?
  • 另外,Table1 和 Table2 是查询。我可以在查询结果中插入一个名为 Rank 的新列吗?我可以在查询中运行这个例程吗?
  • 您确实需要 Sub RankTable 和 EndSub 行。我的代码格式不正确,所以我明白你为什么会这样想。
  • 如果 Table2 是查询,这将不起作用。但是,这很容易解决。将您的查询 Table2 转换为 Make Table 查询并运行它。请务必修改子例程以在查询字符串中包含新表名。每次基础数据发生变化时,请务必运行 Table2 查询以重新制作您的表。
【解决方案2】:

您可以分两步完成:

第 1 步——创建一个计算表 2 排名的查询(例如,命名为“带排名的表 2”)。SQL 可能如下所示:

SELECT
    [Table 2].[Name],
    [Table 2].[Frequency],
    Count(*) AS [Rank]
FROM
    [Table 2],
    [Table 2] AS [Self]
WHERE
    [Self].[Frequency]>=[Table 2].[Frequency]
GROUP BY
    [Table 2].[Name],
    [Table 2].[Frequency];

如果表 2 中存在“关系”(即频率相同的不同名称),则此查询将为两者分配相同的排名。如果您不希望这样做,请更改 WHERE 子句以指定您希望如何打破平局。例如,在平局的情况下,WHERE 子句...

WHERE
    [Self].[Frequency]>[Table 2].[Frequency]
    OR
    ([Self].[Frequency]=[Table 2].[Frequency] AND [Self].[Name]<=[Table 2].[Name])

...将为字母表中排在第一位的名称分配编号较低的等级。

第 2 步——创建另一个查询,将第一个查询连接到表 1。SQL 可能如下所示:

SELECT
    [Table 1].[Name], 
    [Table 1].[Frequency], 
    [Table 2 with Rank].[Frequency] AS [Frequency2], 
    [Table 2 with Rank].Rank AS [RankIn2]
FROM 
    [Table 1] LEFT JOIN [Table 2 with Rank] 
        ON [Table 1].[Name] = [Table 2 with Rank].[Name]
ORDER BY
    [Table 1].[Frequency] DESC;

【讨论】:

  • Step1 给了我一个排名,其中一些行的位置是相同的(相同的排名),即使我使用了您建议的 OR 子句,并且排名缺少数字,因为 os 重复(1,2, 4,4,6,6...)。如果名称中有空格,OR 子句会起作用吗?
  • 对不起。如果使用 OR,则需要将第一个条件更改为使用严格大于比较,如 [Self].[Frequency]&gt;[Table 2].[Frequency]。我已经编辑了我的答案以显示这一点。
  • 谢谢!真的很棒!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-02-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多