访问SQL查询,其中Join没有或错误的结果

时间:2015-08-21 07:05:39

标签: sql ms-access-2003

我在SQL统计页面上遇到了一些问题,希望你能帮助我。

我有两张桌子。 表1:客户(站点)及其名称和机器。好像: Custname,MachineA,MachineB。 Custname是文本,MachineA和MachineB是一个复选框(是/否)

表二:访问(访问),我们可以在其中添加我们为机器客户进行的每次访问。好像: 日期,客户名称,机器。 日期是访问日期,Custname是名称,在Machine中我们可以选择A或B.

现在我想查询每台计算机的一些访问统计信息(用户可以通过表单上的组合框选择)。例如,当我想查看机器A的统计数据时:

  • 我总是希望看到所有拥有机器A
  • 的客户
  • 对于每个客户,我想查看机器A上次访问的日期和机器A的总访问次数。如果该客户的机器A没有访问,它仍然必须显示(女性总访问次数)客户:0)

我已经尝试过这样的东西(在本例中为机器A):

SELECT Sites.Custname, Sites.MachineA, Sites.MachineB, Max(Visits.Date) AS MaxOfDate, Visits.Machine, Count(Visits.Machine) AS CountOfMachine
FROM Visits RIGHT JOIN Sites ON Visits.Custname = Sites.Custname
GROUP BY Sites.Custname, Sites.MachineA, Sites.MachineB, Visits.Machine
HAVING (((Sites.MachineA)=Yes) AND ((Visits.Machine) Is Null Or (Visits.Machine)='A'));

此查询的问题:当客户有机器A和B,并且他们访问了机器B而不是机器A时,它不再出现在机器A的统计中,因为最后一部分SQL:

HAVING (((Sites.MachineA)=Yes) AND ((Visits.Machine) Is Null Or (Visits.Machine)='A'));

他们有机器A,但Visits.Machine不为空(其B)

我无法弄清楚如何解决这个问题!

哦我使用Access 2003模式(mdb)

希望您了解我的问题并拥有一些好的SQL或VBA标记:)

提前致谢!!

2 个答案:

答案 0 :(得分:0)

试试这个

    SELECT Sites.Custname, Sites.MachineA, Sites.MachineB, 
Max(IIF(Visits.Machine='A',Visits.Date,null)) AS MaxOfDate, Visits.Machine, 
sum(IIF(Visits.Machine='A',1,0)) AS CountOfMachine
    FROM Visits RIGHT JOIN Sites ON Visits.Custname = Sites.Custname)
    where Sites.Custname in (select Sites.Custname from Sites where (Sites.MachineA)=Yes)
    GROUP BY Sites.Custname, Sites.MachineA, Sites.MachineB, Visits.Machine

答案 1 :(得分:0)

首先,在WHERE子句而不是HAVING中使用没有聚合的条件语句。通常,HAVING子句包含HAVING Count(*) > 0之类的聚合。见WHERE vs HAVING post。性能不会改变,但它的意图更具人性化。

考虑使用联合查询来组合单独的分组类别。第一个镜像您的原始和第二个返回有机器A B的客户,但访问B A.如果您需要,请与UNION交换UNION ALL在查询不相互排斥的情况下删除重复项。

  SELECT Sites.Custname, Sites.MachineA, Sites.MachineB, Max(Visits.Date) AS MaxOfDate,  
         Visits.Machine, Count(Visits.Machine) AS CountOfMachine
    FROM Visits RIGHT JOIN Sites ON Visits.Custname = Sites.Custname
   WHERE (((Sites.MachineA)=Yes) AND  
     AND ((Visits.Machine) Is Null OR (Visits.Machine)='A'))
GROUP BY Sites.Custname, Sites.MachineA, Sites.MachineB, Visits.Machine;

   UNION 

  SELECT Sites.Custname, Sites.MachineA, Sites.MachineB, Max(Visits.Date) AS MaxOfDate,  
         Visits.Machine, Count(Visits.Machine) AS CountOfMachine
    FROM Visits RIGHT JOIN Sites ON Visits.Custname = Sites.Custname
   WHERE (((Sites.MachineA)=Yes) AND ((Sites.MachineB)=Yes)  
     AND ((Visits.Machine)<>'A' AND (Visits.Machine)='B'))
GROUP BY Sites.Custname, Sites.MachineA, Sites.MachineB, Visits.Machine;