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子句的一部分。这将给我留下以下修改后的代码…请看下面的评论