繁体   English   中英

在另一个联接的结果表上联接,而不使用子查询,CTE或临时表

[英]Join on resultant table of another join without using subquery,CTE or temp tables

我的问题是我们可以在不使用子查询,CTE或临时表的情况下将表A联接到表A和B的内部联接的结果表中吗?

我正在使用SQL Server。

我将举例说明情况

这是两个表GoaLScorersGoalScoredDetails

进球者

gid    Name    
-----------
1       A
2       B
3       A

GoalScored详细信息

DetailId    gid     stadium     goals  Cards
---------------------------------------------
1            1        X          2       1  
2            2        Y          5       2
3            3        Y          2       1

我期望的结果是如果我选择体育场“ X”(或“ Y”)

我应该得到所有可能在该地区得分或未在其中得分的人的名字,以及目标总数,总卡数。

如果没有目标或没有牌,则名称的空值是可接受的。

我可以通过以下查询获得期望的结果

SELECT
    gs.name, 
    SUM(goal) as TotalGoals, 
    SUM(cards) as TotalCards
FROM 
    (SELECT
         gid, stadium, goal, cards 
     FROM
         GoalScoredDetails 
     WHERE 
         stadium = 'Y') AS vtable
RIGHT OUTER JOIN 
    GoalScorers AS gs ON vtable.gid = gs.gid 
GROUP BY 
    gs.name

我的问题是,我们可以不使用子查询,CTE或临时表而得到上述结果吗?

基本上,我们需要做的是将OUTER JOIN GoalScorersINNER JOIN OF GoalScorersGoalScoredDetails INNER JOIN OF GoalScorers结果虚拟表中。

但是我总是面临歧义的列名错误,因为GoalScorers和结果表中都存在“ gid”列。 即使我尝试使用别名作为列名,错误仍然存​​在。

我为此为此创建了一个SQL提琴: http ://sqlfiddle.com/#!3/40162/8

SELECT  gs.name, SUM(gsd.goal) AS totalGoals, SUM(gsd.cards) AS totalCards
FROM    GoalScorers gs
LEFT JOIN GoalScoredDetails gsd ON gsd.gid = gs.gid AND
                                   gsd.Stadium = 'Y'
GROUP BY gs.name;

IOW,您可以将where条件推入连接表达式。

当SQL Server遇到两个或两个以上具有相同列的列且未告知要使用哪个列时,将发生错误模棱两可的列名'ColumnName' 您可以通过在列名前加上完整的表名或别名(如果提供)来避免该错误。 对于以下示例,请使用以下数据:

样本数据

DECLARE @GoalScorers TABLE
    (
        gid        INT,
        Name    VARCHAR(1)
    )
;

DECLARE @GoalScoredDetails TABLE
    (
        DetailId    INT,
        gid            INT,
        stadium        VARCHAR(1),
        goals        INT,    
        Cards        INT
    )
;

INSERT INTO @GoalScorers
    (
        gid,
        Name
    )
VALUES
    (1, 'A'),
    (2, 'B'),
    (3, 'A')
;

INSERT INTO @GoalScoredDetails
    (
        DetailId,
        gid,
        stadium,
        goals,
        Cards
    )
VALUES
    (1, 1, 'x', 2, 1),
    (2, 2, 'y', 5, 2),
    (3, 3, 'y', 2, 1)
;

在第一个示例中,我们收到了错误。 为什么? 由于有不止一列称为gid的列,因此无法确定要使用哪个列。

失败的例子

SELECT 
    gid        
FROM
    @GoalScoredDetails AS gsd
        RIGHT OUTER JOIN @GoalScorers as gs        ON gs.gid = gsd.gid
;

该示例有效,因为我们明确告诉SQL要返回哪个gid:

工作实例

SELECT 
    gs.gid        
FROM
    @GoalScoredDetails AS gsd
        RIGHT OUTER JOIN @GoalScorers as gs        ON gs.gid = gsd.gid
;

您当然可以同时返回:

SELECT 
    gs.gid,       
    gsd.gid
FROM
    @GoalScoredDetails AS gsd
        RIGHT OUTER JOIN @GoalScorers as gs        ON gs.gid = gsd.gid
;

在多表查询中,我总是建议在每个列名前加上表/别名。 这使查询更易于跟踪,并减少了此类错误的可能性。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM