我可以只针对JOIN中的多个表将谓词应用于相同的列吗?

时间:2014-03-08 19:36:54

标签: tsql sql-server-2012

我想将两个表连接在一起,并将两个其他表中的其他信息添加到两个查询表中的相同列。我已经提出了下面的代码,它可以工作,但我不觉得必须为每个表添加另一个JOIN子句,因为如果我想加入/添加它会使查询长得很长更多的事情。

有没有办法将它组合起来,这样我才能加入其他表一次(每次只使用SE别名)?

SELECT
    J.JobId,
    J.StandardJobId,
    S.JobName,
    J.EngineerId,
    E.EngineerName,
    JF.JobId AS FollowUpJobId,
    JF.StandardJobId AS FollowUpStandardJobId,
    SF.JobName AS FollowUpJobName,
    JF.EngineerId AS FollowUpEngineerId,
    EF.EngineerName AS FollowUpEngineerName
FROM
    Jobs J
INNER JOIN
    Jobs JF
ON
    J.FollowUpJobId = JF.JobId
INNER JOIN
    StandardJobs S
ON
    J.StandardJobId = S.StandardJobId
INNER JOIN
    Engineers E
ON
    E.EngineerId = J.EngineerId
INNER JOIN
    StandardJobs SF
ON
    SF.StandardJobId = JF.StandardJobId
INNER JOIN
    Engineers EF
ON
    EF.EngineerId = JF.EngineerId

3 个答案:

答案 0 :(得分:1)

一种方法是使用公用表表达式(CTE) - 类似于:

with cte as
(SELECT J.JobId,
        J.StandardJobId,
        S.JobName,
        J.EngineerId,
        E.EngineerName,
        J.FollowUpJobId
 FROM Jobs J
 INNER JOIN StandardJobs S ON J.StandardJobId = S.StandardJobId
 INNER JOIN Engineers E ON E.EngineerId = J.EngineerId)
SELECT O.*,
       F.StandardJobId AS FollowUpStandardJobId,
       F.JobName AS FollowUpJobName,
       F.EngineerId AS FollowUpEngineerId,
       F.EngineerName AS FollowUpEngineerName
FROM CTE AS O
JOIN CTE AS F ON O.FollowUpJobId = F.JobId

答案 1 :(得分:1)

不,每次需要单独的引用时,都无法避免连接相关表。问题是你不是在使用一般意义上的表,而是使用每个表的特定行,更具体地说,只是那些匹配JOIN和WHERE条件的行。

无法仅指定对StandardJobsEngineers的引用,因为您需要同时处理每个表中的两行,至少在给定的例子中。

但是,取决于您希望使用“附加表格”的方向(针对Jobs的更多引用或StandardJobsEngineers的更多参考{ {1}}),Mark显示的CTE结构可能是抽象它的最简单/最好的方法。我发布这个答案主要是为了解释手头的问题。

答案 2 :(得分:1)

您可以使用CTE(公用表表达式,WITH子句)或视图来执行此操作:

;WITH Jobs_Extended As
(
    SELECT  j.*,
            s.JobName,
            E.EngineerName
    FROM    Jobs         As j
    JOIN    StandardJobs As s   ON s.StandardJobId = j.StandardJobId
    JOIN    Engineer     As e   ON e.EngineerId = j.EngineerId
)
SELECT
    J.JobId,
    J.StandardJobId,
    J.JobName,
    J.EngineerId,
    J.EngineerName,
    JF.JobId         AS FollowUpJobId,
    JF.StandardJobId AS FollowUpStandardJobId,
    JF.JobName       AS FollowUpJobName,
    JF.EngineerId    AS FollowUpEngineerId,
    JF.EngineerName  AS FollowUpEngineerName
FROM    Jobs_Extended   J
JOIN    Jobs_Extended   JF  ON  J.FollowUpJobId = JF.JobId

在此示例中,CTE Jobs_Extended成为Jobs,Engineers和StandardJobs表之间关系的已定义别名。然后,一旦定义,您可以在查询中多次使用它,而无需重新定义这些内部关系。

您可以通过将WITH更改为View来执行相同的操作,这将在您的数据库中生成定义的别名permannet。