Sql server 如何删除此T-SQL查询中包含左外部联接的重复项

Sql server 如何删除此T-SQL查询中包含左外部联接的重复项,sql-server,group-by,left-join,Sql Server,Group By,Left Join,从包含多个左外部联接的查询中提取重复项时遇到问题 SELECT s.Category, SUM(spons.SPONS) AS SPONSOREDAMT, SUM(priv.PRIV) AS PRIVATEAMT FROM (SELECT ID AS ID, Name AS Category FROM dbo.ServicesTable) s LEFT OUTER JOIN (SELECT DISTINCT

从包含多个左外部联接的查询中提取重复项时遇到问题

SELECT s.Category,
       SUM(spons.SPONS) AS SPONSOREDAMT,
       SUM(priv.PRIV)   AS PRIVATEAMT FROM   (SELECT ID   AS ID,
               Name AS Category FROM   dbo.ServicesTable) s
       LEFT OUTER JOIN (SELECT DISTINCT ( ServiceId )   AS ServiceId,
                                        DateCreated,
                                        SUM(SPONSORAMT) AS SPONS
                        FROM   dbo.SponsorMonthlyBill
                        GROUP  BY ServiceId,
                                  DateCreated) spons
         ON ( s.ID = spons.ServiceId )
       LEFT OUTER JOIN (SELECT DISTINCT ( ServiceId )   AS ServiceId,
                                        DateCreated,
                                        SUM(PRIVATEAMT) AS PRIV
                        FROM   dbo.PrivateMonthlyBill
                        GROUP  BY ServiceId,
                                  DateCreated) priv
         ON ( s.ID = priv.ServiceId )
            AND ( MONTH(priv.DateCreated) = MONTH('2011-08-04') )
GROUP  BY s.Category,
          spons.SPONS,
          priv.PRIV 
如果我让最后一行看起来像这样:

GROUP BY s.Category 
与现在不同的是,我将把重复的条目累加起来。如果有两个以上的条目,则所有3个、4个或更多条目相加。那你怎么办呢

天蝎座0给出了一个有效的答案,但需要一些额外的修改。这就是我对它所做的修改:

SELECT  s.Name AS Category,
   SUM(spons.SPONS) AS SPONSOREDAMT,
   SUM(priv.PRIV) AS PRIVATEAMT, SUM(spons.SPONS) + SUM(priv.PRIV) as 
   TOTAL,spons.DateCreated

   FROM   dbo.ServicesTable s
   LEFT OUTER JOIN (SELECT ServiceId,DateCreated,
                           SUM(SPONSORAMT) AS SPONS
                    FROM   dbo.SponsorMonthlyBill
                    GROUP  BY ServiceId,DateCreated) spons
     ON ( s.ID = spons.ServiceId )
   LEFT OUTER JOIN (SELECT distinct ServiceId,
                           SUM(PRIVATEAMT) AS PRIV
                    FROM   dbo.PrivateMonthlyBill
                    GROUP  BY ServiceId
                    ) priv
     ON ( s.ID = priv.ServiceId )
GROUP  BY s.Name,spons.DateCreated

我知道它再次引入了重复项,但是如何将
DateCreated
保留在GROUP BY之外,并且仍然在主SELECT子句中访问它呢?请记住,这是一个视图,其中有一些规则必须遵守。

您的副本是在创建日期之前从您的无用组中获得的

尝试此查询,它将为您提供正确的结果:

SELECT s.Name AS Category,
       SUM(spons.SPONS) AS SPONSOREDAMT,
       SUM(priv.PRIV)   AS PRIVATEAMT
FROM   dbo.ServicesTable s
       LEFT OUTER JOIN (SELECT ServiceId,
                               SUM(SPONSORAMT) AS SPONS
                        FROM   dbo.SponsorMonthlyBill
                        GROUP  BY ServiceId) spons
         ON ( s.ID = spons.ServiceId )
       LEFT OUTER JOIN (SELECT ServiceId
                               SUM(PRIVATEAMT) AS PRIV
                        FROM   dbo.PrivateMonthlyBill
                        WHERE MONTH(DateCreated) = MONTH('2011-08-04')
                        GROUP  BY ServiceId
                        ) priv
         ON ( s.ID = priv.ServiceId )
GROUP  BY s.Name

你的副本来自于你的无用组

尝试此查询,它将为您提供正确的结果:

SELECT s.Name AS Category,
       SUM(spons.SPONS) AS SPONSOREDAMT,
       SUM(priv.PRIV)   AS PRIVATEAMT
FROM   dbo.ServicesTable s
       LEFT OUTER JOIN (SELECT ServiceId,
                               SUM(SPONSORAMT) AS SPONS
                        FROM   dbo.SponsorMonthlyBill
                        GROUP  BY ServiceId) spons
         ON ( s.ID = spons.ServiceId )
       LEFT OUTER JOIN (SELECT ServiceId
                               SUM(PRIVATEAMT) AS PRIV
                        FROM   dbo.PrivateMonthlyBill
                        WHERE MONTH(DateCreated) = MONTH('2011-08-04')
                        GROUP  BY ServiceId
                        ) priv
         ON ( s.ID = priv.ServiceId )
GROUP  BY s.Name

spon
priv
都不包含
ServiceId
列。您正在按它分组,是的,但您没有选择它。忘了?谢谢你的回答,蝎子。但是,我之所以按DateCreated放置group,是因为如果我想将DateCreated公开为spons或priv的属性,并在主SELECT子句中将其用作要显示的字段之一,则需要这样做。此外,此查询位于视图内部,需要datecreated字段,以便我们在报表中按datecreated参数化视图。有什么帮助吗?好吧,把你的完整问题贴出来!原始查询不输出dateCreated,因此您不需要它。如果事实上你需要它,这是一个全新的问题:你需要按创建日期求和吗?创建日期是否仅用于筛选PrivateMonthlyBill月份?等等…我可以参数化视图吗?我知道您可以通过报表来实现这一点,但可以在SQL Server中使用视图吗?我可以做的另一件事是在主SELECT子句、子查询SELECT子句、主GROUPBY子句和子查询GROUPBY子句中包含创建的日期,然后可以在报告中对其进行参数化,正如我在修改后的问题中指定的那样。请走哪条路。你不能参数化一个视图,但是你可以考虑一个(表值)函数,你可以用它来参数化。至于
DateCreated
列,不太清楚该列应该包含哪些值。我的理解是,
DateCreated
保存与特定票据相关的创建日期。现在,您查询的结果集应该包含聚合总和,即一个这样的总和“由”许多账单组成。那么,它们中的哪一个应该
DateCreated
与总和一起表示?我的意思是,
DateCreated
也应该聚合,但问题是,以什么方式<代码>最小值<代码>最大值?其他内容?无论是
spons
还是
priv
都不包含
ServiceId
列。您正在按它分组,是的,但您没有选择它。忘了?谢谢你的回答,蝎子。但是,我之所以按DateCreated放置group,是因为如果我想将DateCreated公开为spons或priv的属性,并在主SELECT子句中将其用作要显示的字段之一,则需要这样做。此外,此查询位于视图内部,需要datecreated字段,以便我们在报表中按datecreated参数化视图。有什么帮助吗?好吧,把你的完整问题贴出来!原始查询不输出dateCreated,因此您不需要它。如果事实上你需要它,这是一个全新的问题:你需要按创建日期求和吗?创建日期是否仅用于筛选PrivateMonthlyBill月份?等等…我可以参数化视图吗?我知道您可以通过报表来实现这一点,但可以在SQL Server中使用视图吗?我可以做的另一件事是在主SELECT子句、子查询SELECT子句、主GROUPBY子句和子查询GROUPBY子句中包含创建的日期,然后可以在报告中对其进行参数化,正如我在修改后的问题中指定的那样。请走哪条路。你不能参数化一个视图,但是你可以考虑一个(表值)函数,你可以用它来参数化。至于
DateCreated
列,不太清楚该列应该包含哪些值。我的理解是,
DateCreated
保存与特定票据相关的创建日期。现在,您查询的结果集应该包含聚合总和,即一个这样的总和“由”许多账单组成。那么,它们中的哪一个应该
DateCreated
与总和一起表示?我的意思是,
DateCreated
也应该聚合,但问题是,以什么方式<代码>最小值<代码>最大值?还有什么吗?从您的代码判断,您似乎认为DISTINCT应用于单个列。事实并非如此。在SQL Server中,DISTINCT总是应用于所有被拉入的列。在这两个子选择中,您都是按
ServiceId
DateCreated
进行分组的,但似乎只有第二个子选择需要这样做,因为
ON
子句中的
MONTH(priv.DateCreated)=MONTH('2011-08-04')
条件。这是真的吗?还是你只是忘记了给第一个左连接添加一个类似的条件?另外,你打算在这种情况下过滤掉什么?您的意思是要筛选出在8月份创建了
date
的行吗?或者应该是具有相同的
ServiceId
行的组,这些行在8月份至少有一个
DateCreated
?我需要能够仅查看8月份完成的事务。实际上,我需要这个查询在一个视图中,该视图将是报表的基础。为了实现这一点,我需要使DateCreated成为顶部select子句的一部分,并成为子查询中其中一个select子句的一部分。这将给我留下以下修改后的代码…请看下面的评论