Access 查询中的 ORDER BY 多值字段

ORDER BY multi-valued field in an Access query

关于我为什么使用多值字段的介绍,如果需要,您可以跳过:我知道多值字段被认为是有害的,但我对它有很好的用途。我有一些物品属于 A 类,一些属于 B 类,还有一些属于两者。类别 A 和类别 B 未在数据库中除此 table 之外的任何地方使用,并且与数据库的其余部分无关,并且 Access 的漂亮 checkbox/combobox 非常适合 select访问适当的类别,这比我使用多对多 table 关系或仅具有两个单独的字段 Category A 和 Category B (特别是因为它非常罕见)两个类别中都有项目)。

话虽这么说,但我无法获得想要的结果。我有一个表单,希望用户能够 select 组合框中的项目,并且我希望它首先显示 A 类中的所有项目(无论它们是否也在 B 类中)然后才显示所有不在类别 A 中的项目,因为类别 A 项目更有可能被用户 select 编辑,所以我希望它们更容易访问。

我没能解决这个问题。我尝试了 ORDER BY、SELECT DISTINCT 等各种选项,但我无法计算出任何适用于多值字段的选项。然后我尝试执行一个查询 select 所有 A 类项目,然后另一个查询 select 所有非 A 类项目。这些查询中的每一个本身都有效,但 Access 不允许我将它们联合在一起。

考虑一个名为 [Supplier] 的 table 以及示例数据

ID  CompanyName  Categories
--  -----------  ----------------------
 1  Company 1    Category A
 2  Company 2    Category B
 3  Company 3    Category A, Category B
 4  Company 4    Category B
 5  Company 5    Category A, Category B

查询

SELECT 
    ID, 
    CompanyName,
    Categories,
    DCount("*", "Supplier", "ID=" & ID & " AND Categories.Value='Category A'") AS CountCatA
FROM
    Supplier

将return

ID  CompanyName  Categories              CountCatA
--  -----------  ----------------------  ---------
 1  Company 1    Category A                      1
 2  Company 2    Category B                      0
 3  Company 3    Category A, Category B          1
 4  Company 4    Category B                      0
 5  Company 5    Category A, Category B          1

因此,我们不使用 DCount() 来填充列,而是在我们的 ORDER BY 子句中使用它

SELECT 
    ID, 
    CompanyName,
    Categories
FROM
    Supplier
ORDER BY
    DCount("*", "Supplier", "ID=" & ID & " AND Categories.Value='Category A'") DESC,
    ID

returning

ID  CompanyName  Categories
--  -----------  ----------------------
 1  Company 1    Category A
 3  Company 3    Category A, Category B
 5  Company 5    Category A, Category B
 2  Company 2    Category B
 4  Company 4    Category B

编辑回复:评论

如果您怀疑 DCount() 函数可能会减慢速度,那么您可以尝试使用 SUM()GROUP BY:

的替代方法
SELECT 
    ID, 
    First(CompanyName_) AS CompanyName, 
    First(Categories_) AS Categories
FROM
    (
        SELECT
            ID,
            CompanyName AS CompanyName_,
            Categories AS Categories_,
            IIf(Categories.Value='Category A',1,0) AS IsPreferredCategory
        FROM Supplier
    )
GROUP BY ID
ORDER BY
    SUM(IsPreferredCategory) DESC,
    ID

请记住,大多数多值数据库系统都能够执行所谓的爆炸 select 或排序。原来Access也有这个能力。

假设以下查询:

SELECT ID, FirstName, Color FROM customers
WHERE ID = 4

注意上面在查询构建器中的样子:

请注意上面如何按照上面的方法扩展 mv 列颜色。

上述查询的结果是:

请注意结果是一条记录(一行)和一个颜色的多值字段(它们是用户最喜欢的颜色)。

请注意在查询构建器中关闭您会看到该列,但请注意您如何 select 子列作为“值”(.value)。

因此我们现在在查询构建器中选择它:

结果 sql 如下所示:

SELECT ID, FirstName, Color.Value FROM customers
WHERE ID =4

结果是这样的:

注意一行是如何变成三行的。这实际上就像对子 table 的 LEFT 连接。这意味着我们可以对此列进行排序。

因此,只需构建一个查询,在其中放入 .value 列,然后您就可以按照您的要求在报告中对这些数据进行排序和分组。

首先显示所有 A 类项目,然后显示包含其他内容的任何记录。所以包含 .value 会爆炸,或者 "expand" 结果查询就好像它是一个单独的 table。因此,您可以根据此结果对报告进行排序。