【问题标题】:How to create SQL that uses input from a Multi-select list in MS Access如何在 MS Access 中创建使用多选列表输入的 SQL
【发布时间】:2020-01-13 10:57:06
【问题描述】:

我有一个 SQL 查询,它根据几个选定的输入为表单创建输出;开始日期,结束日期,商店位置,它工作正常。但是,我需要将商店位置选择器从单选组合框更改为多选列表框。在前者中,我只是引用组合框字段来获取 SQL WHERE 子句的数据。在后者中,可以在列表框中选择一个或多个值,我需要 SQL 使用每个值 (OR'ed) 来获取报告的结果。

我没有尝试过,但我想我必须为每个选定的值运行 SQL,但不确定是否有更好的方法。

SELECT
    Store.District
  , Store.GM_name
  , Store.Location
  , YEAR(Sales.Date_)                                  AS TheYear
  , SUM(Sales.[Total Sales])                           AS SumTotalSales
  , SUM(Sales.[Cust Count])                            AS SumCustCount
  , SUM(Sales.[Total Sales])/SUM([Sales].[Cust Count]) AS AverageTicket
  , SUM(Sales.Payroll)                                 AS SumPayroll
  , SUM(Sales.[Payroll])/SUM([Sales].[Total Sales])    AS PayrollPercent
  , SUM(Sales.[Bonus Pay])                             AS SumBonusPay
  , SUM(Sales.[Holiday Pay])                           AS SumHolidayPay
  , SUM(Sales.[Vacation Pay])                          AS SumVacationPay
  , SUM(Sales.[Sicktime Pay])                          AS SumSicktimePay
  , SUM(Sales.[Cpl Cost])                              AS SumCplCost
  , SUM(Sales.[Cpl Cost])      /SUM([Sales].[Total Sales])   AS CPLCostPct
  , SUM(Sales.[Holiday Pay])   /SUM(Sales.[Total Sales])     AS HolidayPayrollPercent
  , SUM(Sales.[Bonus Pay])     /SUM(Sales.[Total Sales])     AS BonusPayrollPercent
  , SUM([Sales].[Vacation Pay])/SUM([Sales].[Total Sales])   AS VacPayrollPercent
  , SUM([Sales].[Sicktime Pay])/SUM([Sales].[Total Sales])   AS SicktimePayrollPercent
  , SUM(Sales.[Total Food Cost])                             AS SumTotalFoodCost
  , SUM(Sales.[Total Food Cost])/SUM([Sales].[Total Sales])  AS TotalFoodCostPct
  , SUM(Sales.[NGSS Percent])                                AS SumNGSSPercent
  , SUM(Sales.[TA Total Percent])                            AS SumTATotalPercent
  , SUM([Sales.Manager Pay])                                 AS SumManagersPay
  , SUM(Sales.[Manager Pay])/SUM([Sales].[Total Sales])      AS ManagerPayrollPct
  , SUM(Sales.[Training Pay])                                AS SumTrainingPay
  , SUM(Sales.[Training Pay])/SUM([Sales].[Total Sales])     AS TrainingPayrollPct
FROM
    Store
    INNER JOIN
        Sales
    ON
        Store.ID = Sales.Store_ID
    --> This WHERE is where the single store location is retrieved,
     --> but need to get all selected locations on the SelectedStore
    --> control and OR these results
WHERE
    (
        (
            (
                Store.Location
            )
            =[Forms]![Startup]![SelectedStore].[value]
        )
        AND
        (
            (
                Sales.Date_
            )
            BETWEEN [Forms]![Startup]![StartDateToView] AND [Forms]![Startup]![EndDateToView]
            OR
            (
                Sales.Date_
            )
            BETWEEN DATEADD("yyyy",-1,[Forms]![Startup]![StartDateToView]) AND DATEADD("yyyy",-1,[Forms]![Startup]![EndDateToView])
        )
    )
GROUP BY
    Store.District
  , Store.GM_name
  , Store.Location
  , YEAR(Sales.Date_);

【问题讨论】:

  • How to fomat sql."我没有尝试过,但我想我必须为每个选定的值运行 SQL" 为什么不呢?在问题标题(复制和粘贴)上询问网络,应该是强制性的!

标签: sql forms ms-access


【解决方案1】:

如果您在 VBA 中构建此查询,则构建一个针对所选值的 OR 查询相对简单。但大概这是针对保存的查询,或者保存在需要 SQL 的属性中的查询;并且您不想在每次更改列表框中的选择时重写 SQL。

我能想到两种可能:

  • 如果您可以使用 VBA,您可以编写一个接受值和列表框的函数。不幸的是,我无法直接传递列表框——假设我想要列表框的值,而不是列表框本身——但传递表单和列表框的名称是有效的:

    Function InListbox(value As Variant, formName As String, listboxName As String) As Boolean
        Dim lb As ListBox
        Set lb = Forms(formName)(listboxName)
    
        Dim index As Variant
        For Each index In lb.ItemsSelected
            If lb.Column(0, index) = value Then
                InListbox = True
                Exit Function
            End If
        Next
    End Function
    

    然后您可以在 SQL 中使用该函数,如下所示:

    SELECT Table1.ID, Table1.Text
    FROM Table1
    WHERE InListbox(Table1.Text, "Form1", "List0")
    
  • 或者,您可以处理列表框上的选择更改,将选定的值写入专用表(并清除未选定的值);然后,您可以在该表上加入您的查询。

    这种方法有一个缺点(正如 ComputerVersteher 所说的 here)。当您删除 Access 数据库中的记录时,Access 不会重用留下的空间;添加记录会增加数据库的大小。因此,您需要经常压缩数据库,以释放这些空白空间。

【讨论】:

  • 是的,我可以使用 VBA。我对其进行了编码以在列表框中查找值(并将它们放在文本框中),但是我感到困惑的是尝试使用您提到的选项一。如何在查询中使用函数?
  • @Rich 就像任何其他功能一样。 :) 如果您有一个名为 Function MyFunction(lb As Variant) As Boolean 的函数,您可以在 SQL 中将其调用为 MyFunction(Forms!Form1!MyListbox)。我会尽快提供一些示例代码。
  • @Rich 我已经用一些示例代码更新了我的答案。
【解决方案2】:

感谢 Zev 的输入。我使用了第二种方法,首先使用选择创建和填充临时表。然后我使用第二个 INNER JOIN(在第一个之前)将 store.location 与 tempTable.location 连接起来以缩小结果范围。

【讨论】:

  • 请注意,访问表在删除后需要压缩以减小其大小。
猜你喜欢
  • 1970-01-01
  • 2021-05-20
  • 1970-01-01
  • 1970-01-01
  • 2013-05-26
  • 1970-01-01
  • 2012-09-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多