优化MS Access Double SubQuery

时间:2015-05-29 14:53:19

标签: sql ms-access subquery ms-access-2010

我正在构建的这个MS Access查询非常慢。我只测试一个月的数据(一个表驱动这个查询,有28,577条记录,36列)。

以下是我要完成的事情:

我想按模型返回以特定交易类型出售的独特车辆的数量(此数据库未规范化,并且是从加载到表格中的Excel工作表构建的)。

存在第一个子查询,因为我理解在Access中您不能将DISTINCT语句与聚合函数一起使用。所以我需要构建一个子查询来处理Count(DISTINCT VIN)。

第二个子查询是我认为的罪魁祸首。每个VIN可能有许多条目。例如,车辆可能已经使用我正在计算的交易类别之一,然后取消,并转售到我不想计算的交易类别之一。这将为此VIN生成三条记录:

  1. 销售到我认为我想要计算的交易类别
  2. 取消首次销售
  3. 转售为我不想算的交易类别
  4. 第二个子查询检查VIN是否有“已取消的销售”记录,然后不包括计数中的第一个Sale。

    希望我能很好地解释这一点,并且有人可以为我提供一个加速查询的潜在解决方案。

    感谢

    查询

    PARAMETERS [Enter Sales Month Start Date] DATETIME, [Enter Sales Month End Date] 
    DATETIME; 
    
    SELECT DSTNCT_COUNT.trans      AS Trans, 
           DSTNCT_COUNT.mdl        AS Model, 
           Count(DSTNCT_COUNT.cnt) AS VIN_COUNT 
    FROM   (SELECT DISTINCT new_bbss.vin              AS cNt, 
                            new_bbss.[model category] AS MDL, 
                            new_bbss.[trans category] AS Trans 
            FROM   new_bbss 
            WHERE  ( ( ( new_bbss.[trans category] ) NOT LIKE 'Individual' 
                       AND ( new_bbss.[trans category] ) NOT LIKE 'Corporate' 
                       AND ( new_bbss.[trans category] ) NOT LIKE 'Cancel' 
                       AND ( new_bbss.[trans category] ) NOT LIKE 'Partners' 
                       AND ( new_bbss.[trans category] ) NOT LIKE 'Special' 
                       AND ( new_bbss.[trans category] ) NOT LIKE 'Employee' 
                       AND ( new_bbss.[trans category] ) NOT LIKE 'Mobile' 
                       AND ( new_bbss.[trans category] ) NOT LIKE 'JLR FLEET' ) 
                       AND ( ( new_bbss.[retailer code] ) LIKE 'R*' ) ) 
                       AND new_bbss.[trans date] BETWEEN [enter sales month start date] 
                                                 AND 
                                                     [enter sales month end date] 
                       AND new_bbss.vin NOT IN(SELECT new_bbss.vin 
                                               FROM   new_bbss 
                                               WHERE  new_bbss.[trans category] LIKE 
                                                  'CancelVIP*' 
                                                   OR new_bbss.[trans category] LIKE 
                                                      'CancelDealer Local*' 
                                                   OR new_bbss.[trans category] LIKE 
                                                      'CancelLoaner*' 
                                                   OR new_bbss.[trans category] LIKE 
                                                      'CancelAlive*'))
           AS DSTNCT_COUNT 
    GROUP  BY trans, mdl; 
    

1 个答案:

答案 0 :(得分:1)

对于NOT IN,MsAccess应该比在NOT EXISTS上慢。我不知道这是否属实,但无论如何你都可以尝试。此外,您可以将此限制从WHERE子句移动到HAVING子句,因为vin在GROUP BY子句中。这可能会减少MsAccess查看的时间。

select [model category], [trans category], count(*)
from
(
  select [model category], [trans category], vin
  from new_bbss
  where [trans category] not like 'Individual' 
    and [trans category] not like 'Corporate' 
    and [trans category] not like 'Cancel' 
    and [trans category] not like 'Partners' 
    and [trans category] not like 'Special' 
    and [trans category] not like 'Employee' 
    and [trans category] not like 'Mobile' 
    and [trans category] not like 'JLR FLEET' 
    and [retailer code] like 'R*'
    and [trans date] between [enter sales month start date] 
                         and [enter sales month end date] 
  group by [model category], [trans category], vin
  having not exists
  (
    select *
    from new_bbss unwanted
    where unwanted.vin = new_bbss.vin
    and  
    (    unwanted.[trans category] like 'CancelVIP*' 
      or unwanted.[trans category] like 'CancelDealer Local*' 
      or unwanted.[trans category] like 'CancelLoaner*' 
      or unwanted.[trans category] like 'CancelAlive*'
    )
  )
) matches
group by [model category], [trans category];
BTW:应该有一个关于vin的索引,所以MsAccess可以快速查找其记录。