SQL连接表给出错误的结果

时间:2018-07-17 07:20:06

标签: sql sql-server tsql

我正在执行此查询:

SELECT S.CompanyName,
     COUNT(Visit.Id) AS visit_number,
     COUNT(Client.Id) AS client_number,
     FROM S
     JOIN Visit ON S.Id = Visit.SnId
     JOIN Client ON S.Id = Client.SId
     WHERE Visit.StartedAt >= '2017.01.01' AND Visit.EndedAt< '2018.07.07' 
     GROUP BY S.CompanyName;

结果表如下:

company_name   visit_number   client_number
compnay_name_1    4               4
company_name_2    75              75

。 。

这些是错误的数字。当我在不连接表的情况下执行查询时,它会给出正确的结果,这与firs查询的结果不同。 我很确定我没有犯任何错误。我读了很多问题来证明我的查询是正确的,但仍然找不到出路。错误在哪里?

SELECT S.CompanyName, COUNT(Visit.Id) AS visit_number
    FROM S
    JOIN Visit ON S.Id = Visit.SId
    WHERE Visit.StartedAt >= '2017.01.01' AND Visit.EndedAt< '2018.07.07' 
    GROUP BY S.CompanyName;

此查询给出如下表:

company_name   visit_number   

    compnay_name_1    3              
    company_name_2    54          

哪有什么像拳头一样。我期望第一个查询在visit_number列中包含此结果。

3 个答案:

答案 0 :(得分:2)

由于双join,在某些地方您具有一对多的关系。我认为您应该使用:

COUNT(DISTINCT Visit.Id) AS visit_number,
COUNT(DISTINCT Client.Id) AS client_number,

答案 1 :(得分:2)

您正在沿着两个独立的维度进行汇总。一种解决方案是使用join。但是,这可能需要大量的计算。

推荐的替代方法通常是在SELECT s.CompanyName, v.num_visits, c.num_clients FROM s LEFT JOIN (SELECT v.snid, COUNT(*) as num_visits FROM Visit v WHERE v.StartedAt >= '2017-01-01' AND v.EndedAt < '2018-07-07' GROUP BY v.snid ) v ON s.Id = v.SnId LEFT JOIN (SELECT c.sid, COUNT(*) as num_clients FROM Client c GROUP BY c.snid ) v ON s.Id = c.SId GROUP BY s.CompanyName; 之前 进行聚合:

LEFT JOIN

请注意,这使用for string in list: if list.count(string) > 1: print(string+" appeared: ") print(list.count(string)) elif list.count(string) == 1: print(string) ,因此即使没有访问或客户,也将退回所有公司。

答案 2 :(得分:0)

JOIN Visit ON S.Id = Visit.SnId

这不是吗:

JOIN Visit ON S.Id = Visit.SId

或者,用LEFT JOIN替换JOIN可能会有帮助