加入不正确过滤

时间:2017-03-10 20:57:04

标签: sql

我正在努力让这个查询显示正确的数据。

SELECT a.ReportDate
    ,a.ClientName
    ,count(a.ADUsername) AS UserCount
    ,sum(b.ShareData + b.UserData) AS DataUsage
    ,sum(d.UsedSpace) AS SQLUsage
FROM TableA AS a
    JOIN TableB AS b
        ON a.ClientName = b.ClientName AND a.ReportDate = b.ReportDate
    JOIN TableC AS c
        ON a.ClientName = c.ClientName AND b.ClientName = c.ClientName
    JOIN TableD AS d
        ON c.SQLInstance = d.ServerInstance AND a.ReportDate = d.ReportDate
WHERE a.ClientName = @client AND a.ReportDate = @date
GROUP BY a.ReportDate,a.ClientName

列显示,但其中的数据不正确。特别是UserCount,DataUsage和SQLUsage列的数字远大于它应该的数量。回顾一下发生的事情:

TableA包含一个名称列表,我需要对指定日期的名称进行计数 TableB包含2列数字数据,需要与TableA中的相同客户名和日期匹配 TableC是TableA和表B中每个客户名称的信息数据 TableD有更多的数值数据列,需要匹配TableC中与TableA和TableB中的客户端名称匹配的实例名称以及报告日期。

任何帮助都将不胜感激。

编辑:以下是此查询的结果:

ReportDate | ClientName | UserCount | DataUsage | SqlUsage
03/09/2017 | Client | 175 | 125531.00 | 168816.20

如果我在表A和B上进行联接,我会得到正确的数据。

SELECT a.ReportDate,a.ClientName
    ,count(a.ADUsername) AS UserCount
    ,sum(b.ShareData + b.UserData) AS DataUsage
FROM TableAs AS a
    LEFT JOIN TableB AS b
        ON a.ClientName = b.ClientName
WHERE a.ClientName = @client AND a.ReportDate = @date
GROUP BY a.ReportDate,a.ClientName

返回:

ReportDate | ClientName | UserCount | DataUsage
03/09/2017 | Client | 7 | 5021.24

然后为SQLUsage做总和

SELECT sum(UsedSpace)
FROM TableD
WHERE ServerInstance = @instance AND ReportDate = @date

给我24116.60

所有这些信息都是正确的。

1 个答案:

答案 0 :(得分:0)

我想我知道这里发生了什么:

您希望获取具有多个用户的特定客户端(=主机)的报告。它们中的每一个都在表A和B中生成一行。

因此,当该计算机上有5个用户时,您从表A中选择所有用户并将其与表B中的所有用户交叉,共计25个组合(您只匹配clientName和reportDate,但如果有超过1个用户,他们相乘)。

此外,您计算整个计算机的已用空间,但是为该计算机上找到的每个用户提取此空间。所以当然这个值太大了。

  • 应确保表A中的一行确实只匹配表B中的一行
  • 应确保仅计算机器的已用空间一次(或总结表A和B中单个用户使用的空间)
  • 应该删除两个条件ON a.ClientName = c.ClientName AND b.ClientName = c.ClientName中的一个,因为在第一个连接中,您定义了A.clientName = B.clientName。所以你只需要将其中一个与c.clientName进行比较(这是一个数学公理,如果a = b且b = c则a = c)