Side JOINing table 的多个子集
Side JOINing multiple subsets of a table
我正在尝试在 table 的一个子集和同一 table 的每个其他子集之间进行完全连接,即使缺少某些行也是如此。我有一个 table 的形式:
CREATE TABLE #Test (
SiteID int NOT NULL
, DayOfWeekID tinyint NOT NULL
, Quantity float NOT NULL );
这是一周中每一天每个站点的销售量。然后我使用 SiteID = -1 作为聚合(平均值),我正在寻找每个站点和这个平均值之间的错误,例如
CREATE TABLE #TestError (
SiteID int NOT NULL
, Error float NOT NULL );
INSERT INTO #TestError
( SiteID
, Error
)
SELECT t1.SiteID
, SUM(ABS(isnull(t1.Quantity, 0) - t2.Quantity))
FROM #Test t1
JOIN #Test t2
ON t1.DayOfWeekID = t2.DayOfWeekID
AND t2.SiteID = -1
GROUP BY t1.SiteID;
只要对于每个 SiteID,一周中的所有 7 天都存在,这就可以正常工作。但是,如果一个网站在一周中的某一天没有销售额,那么该行就会从总和中丢失,并且报告的错误将低于应有的水平。另一方面,如果我使用 RIGHT JOIN 而不是 JOIN,我不能按 t1.SiteID 分组,因为该值在生成的行中将为 NULL。显而易见的答案是,我需要通过将 #Test 实例化为 table 的 SiteID 和包含 DayOfWeekIDs 1-7 的 table 之间的交叉连接来确保每个 SiteID 都有全部 7 天,并具有初始数量零,然后用它们存在的实际值更新它。但这似乎效率低下,更广泛地说,这是我以前遇到过的事情,我想了解编写这种连接的 'proper' SQL 方式。谢谢!
如果站点 -1
有一周中的所有日子,您可以 cross join
它的记录与不同站点的列表,然后将 table 与 left join
和汇总:
select s.siteid, sum(abs(coalesce(t1.quantity, 0) - t0.quantity)) as diff
from #test t0
cross join (select distinct siteid from #test) s
left join #test t1 on t1.dayofweekid = t0.dayofweekid and t1.siteid = s.siteid
where t0.siteid = -1
group by s.siteid
我正在尝试在 table 的一个子集和同一 table 的每个其他子集之间进行完全连接,即使缺少某些行也是如此。我有一个 table 的形式:
CREATE TABLE #Test (
SiteID int NOT NULL
, DayOfWeekID tinyint NOT NULL
, Quantity float NOT NULL );
这是一周中每一天每个站点的销售量。然后我使用 SiteID = -1 作为聚合(平均值),我正在寻找每个站点和这个平均值之间的错误,例如
CREATE TABLE #TestError (
SiteID int NOT NULL
, Error float NOT NULL );
INSERT INTO #TestError
( SiteID
, Error
)
SELECT t1.SiteID
, SUM(ABS(isnull(t1.Quantity, 0) - t2.Quantity))
FROM #Test t1
JOIN #Test t2
ON t1.DayOfWeekID = t2.DayOfWeekID
AND t2.SiteID = -1
GROUP BY t1.SiteID;
只要对于每个 SiteID,一周中的所有 7 天都存在,这就可以正常工作。但是,如果一个网站在一周中的某一天没有销售额,那么该行就会从总和中丢失,并且报告的错误将低于应有的水平。另一方面,如果我使用 RIGHT JOIN 而不是 JOIN,我不能按 t1.SiteID 分组,因为该值在生成的行中将为 NULL。显而易见的答案是,我需要通过将 #Test 实例化为 table 的 SiteID 和包含 DayOfWeekIDs 1-7 的 table 之间的交叉连接来确保每个 SiteID 都有全部 7 天,并具有初始数量零,然后用它们存在的实际值更新它。但这似乎效率低下,更广泛地说,这是我以前遇到过的事情,我想了解编写这种连接的 'proper' SQL 方式。谢谢!
如果站点 -1
有一周中的所有日子,您可以 cross join
它的记录与不同站点的列表,然后将 table 与 left join
和汇总:
select s.siteid, sum(abs(coalesce(t1.quantity, 0) - t0.quantity)) as diff
from #test t0
cross join (select distinct siteid from #test) s
left join #test t1 on t1.dayofweekid = t0.dayofweekid and t1.siteid = s.siteid
where t0.siteid = -1
group by s.siteid