在不使用子查询,CTE或临时表

时间:2015-12-24 10:51:30

标签: sql sql-server database

我的问题是我们可以将表A连接到表A和B的内连接的结果表而不使用子查询,CTE或临时表吗?

我正在使用SQL Server。

我将用一个例子

来解释这种情况

这两个表GoaLScorersGoalScoredDetails

射手

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

GoalScoredDetails

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的结果虚拟表格。

但是我总是遇到模糊的列名错误,因为“{1}}中的”gid“列以及结果表中都存在。即使我尝试为列名使用别名,错误仍然存​​在。

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

2 个答案:

答案 0 :(得分:3)

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,你可以把你的标准推到加入表达式上。

答案 1 :(得分:0)

错误不明确的列名称' ColumnName' 在SQL Server遇到两个或多个具有相同列的列时发生,并且没有告知要使​​用哪个列。您可以通过在列名称前加上完整的表名称或别名(如果提供)作为前缀来避免错误。对于以下示例,请使用以下数据:

样本数据

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
;

在多表查询中,我总是建议为每个列名前缀一个表/别名。这使查询更容易遵循,并降低了此类错误的可能性。