Sql 将第三个表作为左联接引入会复制值

Sql 将第三个表作为左联接引入会复制值,sql,sql-server,join,left-join,Sql,Sql Server,Join,Left Join,如何设置此左连接,使其不会重复表2中的呼叫或表3中的销售 左键连接到表2或表3会返回准确的答案,左键连接到同一个查询中的两个都是重复的-虽然我有三次通话,销售额为444美元,但它会返回6次通话(表2的三条记录x表3的两条记录),销售额为1332美元 使用SQLServerStudio 17 CREATE TABLE #Table1 ( CommercialTime datetime, NextCommercialTime datetime, Station varchar

如何设置此左连接,使其不会重复表2中的呼叫或表3中的销售

左键连接到表2或表3会返回准确的答案,左键连接到同一个查询中的两个都是重复的-虽然我有三次通话,销售额为444美元,但它会返回6次通话(表2的三条记录x表3的两条记录),销售额为1332美元

使用SQLServerStudio 17

CREATE TABLE #Table1 (
    CommercialTime datetime,
    NextCommercialTime datetime,
    Station varchar(4),
    Cost int    )
INSERT INTO #Table1 (
    CommercialTime,
    NextCommercialTime,
    Station,
    Cost    )
VALUES
(   '2020-04-06 12:01:00.000',
    '2020-04-06 12:15:00.000',
    'ZZZZ',
    '9999'  )

CREATE TABLE #Table2 (
    CallTime datetime,
    Station varchar(4),
    CallCount int   )
INSERT INTO #Table2 (
    CallTime,
    Station,
    CallCount   )
VALUES
(   '2020-04-06 12:02:00.000',
    'ZZZZ',
    '1' ),
(   '2020-04-06 12:05:00.000',
    'ZZZZ',
    '1' ),
(   '2020-04-06 12:07:00.000',
    'ZZZZ',
    '1' )

CREATE TABLE #Table3 (
    SaleTime datetime,
    Station varchar(4),
    SaleAmount int  )
INSERT INTO #Table3 (
    SaleTime,
    Station,
    SaleAmount  )
VALUES
(   '2020-04-06 12:04:00.000',
    'ZZZZ',
    '123'   ),
(   '2020-04-06 12:07:00.000',
    'ZZZZ',
    '321'   )

SELECT 
          one.Station
        , SUM(two.Callcount) as Calls
        , SUM(three.SaleAmount) as Sales
    FROM #Table1 one WITH(NOLOCK)
    LEFT JOIN #Table2 two   WITH(NOLOCK)    ON one.Station = two.Station 
                                                AND two.CallTime between one.CommercialTime and one.NextCommercialTime      
    LEFT JOIN #Table3 three WITH(NOLOCK)    ON one.Station = three.Station 
                                                AND three.SaleTime between one.CommercialTime and one.NextCommercialTime    
    GROUP BY one.Station

--Output:
    Station Calls   Sales
    ZZZZ    6   1332

对于这个问题,我建议使用子查询而不是连接,例如

SELECT 
  one.Station
  , (
    select sum(CallCount)
    from #Table2 two
    where one.Station = two.Station 
    AND two.CallTime between one.CommercialTime and one.NextCommercialTime
  ) Calls
  , (
    select sum(SaleAmount)
    from #Table3 three
    where one.Station = three.Station 
    AND three.SaleTime between one.CommercialTime and one.NextCommercialTime
  ) Sales
FROM #Table1 one
原因是,联接提供的每一行组合都不是您想要的。为了解释,当您将表2连接到表1上时,会得到3行:

Station TwoCallTime
ZZZZ    2020-04-06 12:02:00.000
ZZZZ    2020-04-06 12:05:00.000
ZZZZ    2020-04-06 12:07:00.000
因此,当您在表3上加入时,它有2行,现在有6行:

Station TwoCallTime             ThreeCallTime
ZZZZ    2020-04-06 12:02:00.000 2020-04-06 12:04:00.000
ZZZZ    2020-04-06 12:02:00.000 2020-04-06 12:07:00.000
ZZZZ    2020-04-06 12:05:00.000 2020-04-06 12:04:00.000
ZZZZ    2020-04-06 12:05:00.000 2020-04-06 12:07:00.000
ZZZZ    2020-04-06 12:07:00.000 2020-04-06 12:04:00.000
ZZZZ    2020-04-06 12:07:00.000 2020-04-06 12:07:00.000

这并不是您在这里想要实现的。

您可以使用
外部应用

SELECT one.Station, ISNULL(t2.calls, 0) AS Calls, ISNULL(t3.sales, 0) AS Sales
FROM #Table1 one WITH(NOLOCK) OUTER APPLY
     ( SELECT SUM(two.Callcount) as calls
       FROM #Table2 two
       WHERE one.Station = two.Station AND 
             two.CallTime between one.CommercialTime and one.NextCommercialTime      
     ) t2 OUTER APPLY
     ( SELECT SUM(three.SaleAmount) as sales
        FROM #Table3 three
        WHERE one.Station = three.Station AND 
              three.SaleTime between one.CommercialTime and one.NextCommercialTime    
     ) t3;

这是一个常见的错误,人们希望某些子查询的某些联接(每个联接可能涉及不同的键),每个子查询可能涉及联接和/或聚合,但他们错误地尝试进行所有联接,然后进行所有聚合,或者在以前的聚合上进行聚合。在适当的行上写入单独的总和和/或对案例语句行进行总和;在公共唯一列集上联接。PS In a:找到第一个子表达式,它是您可以显示的代码,它执行您期望的操作,并由不执行您期望的操作的代码扩展。然后解释你的期望和原因。这是一个常见问题解答。在考虑发帖之前,请阅读本手册,谷歌搜索任何错误信息,或您的问题/问题/目标的许多清晰、简洁和准确的措辞,包括或不包括您的特定字符串/名称和网站:stackoverflow.com&tags;阅读许多答案。如果你发布一个问题,用一句话作为标题。反思你的研究。请参见文本上方的投票箭头(&S)。除非我们努力(重新)写清楚,否则我们无法推理、交流或搜索。这能回答你的问题吗@DonnaC下面的答案对你有帮助吗?你是新来的吗?你认为使用子查询更好还是不同?在这种情况下,如果使用了
outerapply
,这相当于使用子查询(实际上,如果两个表中都没有匹配项,它会过滤掉行)。然而,横向联接比子查询强大得多。有些人喜欢将表引用保存在
FROM
子句中,而不是分散在整个查询中。在这个问题的上下文中,子查询更准确,因为问题明确提到了左连接。