【问题标题】:Join on resultant table of another join without using subquery,CTE or temp tables在不使用子查询、CTE 或临时表的情况下加入另一个连接的结果表
【发布时间】:2015-12-24 10:51:29
【问题描述】:

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

我正在使用 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”)

我应该得到所有可能或可能没有在那里得分的人的名字,以及总进球数,总牌数。

如果没有目标或没有卡片,名称可以接受 Null 值。

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

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

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

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

【问题讨论】:

  • 如果您在引用列时始终使用表名或别名,您将避免错误。示例:SELECT gid 不包含 SQL 所需的所有信息,而 SELECT gs.gid 包含。
  • @destination-data 主要问题是如何在结果表中设置别名或指定 gid 列。即使我在 select 中分配了别名,它也不能用于加入,除非它是子查询

标签: sql sql-server database


【解决方案1】:
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 条件推送到连接表达式。

【讨论】:

  • 谢谢。我知道他们是完成这项工作的一种方法,但不知道如何做。非常感谢。
【解决方案2】:

当 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
;

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

【讨论】:

    猜你喜欢
    • 2015-05-03
    • 1970-01-01
    • 2013-02-27
    • 1970-01-01
    • 1970-01-01
    • 2013-10-28
    • 2016-05-23
    • 1970-01-01
    相关资源
    最近更新 更多