使用LEFT JOIN和Aggregate函数的MS Access链接表查询未返回预期结果

时间:2012-12-11 20:47:05

标签: sql

我有一个在SQL db上运行时输出以下结果的查询

CreatedDate                 QuoteNumber NumberOfLicensedDrivers
2012-07-01 10:38:49.157 48641           0
2012-07-01 18:35:38.680 48650           2
2012-07-02 08:44:33.770 48670           1
2012-07-02 09:12:09.447 48700           0

我为了这篇文章简化了查询,但它基本上是:

SELECT DISTINCT
       CreatedDate,
       QuoteNumber,
       count([DriversLicense]) as NumberOfLicensedDrivers
FROM table1 LEFT OUTER JOIN table2 on table2.QuoteID = table1.ID 
WHERE CreatedDate > '7/1/2012'
GROUP BY QuoteNumber, CreatedDate 
ORDER BY CreatedDate ASC

此查询为我提供了预期的输出。我希望所有引号都显示在我的输出中。如果有0个驱动程序我想要显示0。问题是我需要在链接表的MS访问中创建相同的结果。 MS访问输出没有给我预期的结果。

以下是我用于MS ACCESS的查询

SELECT DISTINCT 
     quote.CreatedDate, 
     quote.QuoteNumber, 
     count(quoteDrivers.DriversLicense) As NumberOfLicensedDrivers
FROM quote 
LEFT JOIN quoteDrivers ON quote.ID = quoteDrivers.QuoteID
WHERE (quote.CreatedDate>#7/1/2012#)
GROUP BY quote.CreatedDate, quote.QuoteNumber
ORDER BY quote.CreatedDate;

输出显示没有许可的驱动程序:

CreatedDate            QuoteNumber  NumberOfLicensedDrivers
7/1/2012 10:38:49 AM   48641    0
7/1/2012 6:35:39 PM    48650    0
7/2/2012 8:44:34 AM    48670    0
7/2/2012 9:12:09 AM    48700    0

但是当我对quoteDrivers表添加额外的WHERE子句时:

SELECT DISTINCT 
    quote.CreatedDate, 
    quote.QuoteNumber, 
    count(quoteDrivers.DriversLicense) As NumberOfLicensedDrivers
FROM quote 
LEFT JOIN quoteDrivers ON quote.ID = quoteDrivers.QuoteID
WHERE (quote.CreatedDate>#7/1/2012#)
and quoteDrivers.DriverAddedDate >#1/1/2012# ''Added this
GROUP BY quote.CreatedDate, quote.QuoteNumber
ORDER BY quote.CreatedDate;

我得到了预期的结果(减去带有0个驱动程序的报价)

CreatedDate         QuoteNumber NumberOfLicensedDrivers
7/1/2012 6:35:39 PM 48650           2
7/2/2012 8:44:34 AM 48670           1

任何人都可以解释为什么我没有在quoteDrivers表的where子句中指定列来获取驱动程序的数量?

4 个答案:

答案 0 :(得分:1)

不确定Access是否支持此功能,但在一般情况下,将条件移动到连接中的on子句会使查询的“外部”部分保持工作

Select
  quote.CreatedDate, 
  quote.QuoteNumber, 
  count(quoteDrivers.DriversLicense) As NumberOfLicensedDrivers
From
  quote 
    Left Join
  quoteDrivers 
    On quote.ID = quoteDrivers.QuoteID And quoteDrivers.DriverAddedDate > #1/1/2012#
Where
  quote.CreatedDate > #7/1/2012#
Group By
  quote.CreatedDate, 
  quote.QuoteNumber
Order By
  quote.CreatedDate;

此外,你的分歧对于这个群体来说是多余的。可能优化器足够智能,不会变慢,但为什么要抓住机会!

答案 1 :(得分:1)

一个特定修复:您可以在封装了连接服务器端的sql server上创建一个视图,然后在Access中链接到视图作为链接表。 还要检查日期变量逻辑,尝试将其替换为DateDiff函数,以避免根据本地设置对硬编码日期文字进行不同解释的问题

答案 2 :(得分:1)

我建议重新编写查询,如下所示:

SELECT CreatedDate, QuoteNumber, Count(*) as NumberOfLicensedDrivers
FROM (
    SELECT q.CreatedDate, q.QuoteNumber, qd.DriversLicense
    FROM quote q INNER JOIN quoteDrivers qd ON q.ID = qd.QuoteID
    WHERE q.CreatedDate > #7/1/2012#
) X
GROUP BY CreatedDate, QuoteNumber
ORDER BY 1

通过组合子查询中的表,然后从中获取驱动程序的数量,查询表单适合MS SQL服务器SQL和MS Jet SQL(MS访问SQL)的规则集,因此可用的范围较小ms访问“做错了”,结果集应该是相同的。

我只是不确定dateformat#..#;在SQL中,这通常是'..';如果后端是另一个ms访问数据库,格式#..#将是必需的,但是如果它是sql,'..'可能会更好 - 虽然我不能说某些随便,所以你可能想测试这个。

希望这会有所帮助: - )

答案 3 :(得分:0)

我的愚蠢抓住了我。我不确定为什么以下查询有效。

SELECT DISTINCT 
    quote.CreatedDate, 
    quote.QuoteNumber, 
    count(quoteDrivers.DriversLicense) As NumberOfLicensedDrivers
FROM quote 
LEFT JOIN quoteDrivers ON quote.ID = quoteDrivers.QuoteID
WHERE (quote.CreatedDate>#7/1/2012#)
and quoteDrivers.DriverAddedDate >#1/1/2012# 
GROUP BY quote.CreatedDate, quote.QuoteNumber
ORDER BY quote.CreatedDate;

quoteDrivers.QuoteID是一个字符串,quote.ID是一个GUID。创建链接表时MS访问会在GUIDS周围添加括号{}。我不确定为什么只有在我对quoteDrivers表添加了where子句时查询才有效。

以下查询完全符合我的要求。

SELECT DISTINCT 
    quote.CreatedDate, 
    quote.QuoteNumber, 
    count(quoteDrivers.DriversLicense) As NumberOfLicensedDrivers
FROM quote 
LEFT JOIN quoteDrivers ON quote.ID = "{" + quoteDrivers.QuoteID + "}"
WHERE (quote.CreatedDate>#7/1/2012#)
GROUP BY quote.CreatedDate, quote.QuoteNumber
ORDER BY quote.CreatedDate;

我应该事先解释一下列结构,很抱歉不这样做。如果有人能解释为什么我的联接工作时我在quoteDrivers表("and quoteDrivers.DriverAddedDate >#1/1/2012#")上添加了一个where子句,我真的很感激。