Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 直接或通过中介将第三个表与第一个表连接_Sql Server_Tsql_Sql Server 2008 R2_Left Join - Fatal编程技术网

Sql server 直接或通过中介将第三个表与第一个表连接

Sql server 直接或通过中介将第三个表与第一个表连接,sql-server,tsql,sql-server-2008-r2,left-join,Sql Server,Tsql,Sql Server 2008 R2,Left Join,我试图连接3个表,其中第三个表包含对第二个表和第一个表的引用;我想要这些参考的结果。然而,在第三个表引用第一个表的地方,我不需要第二个表的结果 这很难解释,所以我已经用下面的例子说明了我想要什么 第一个select语句生成6行;我明白为什么,但那不是我想要的 第二个2给出了我想要的结果,但它们有一种代码味道。有谁能提出更好的方法来实现同样的产出 另请参见SQL Fiddle: 更新 我只是想到了另一个解决方案,感觉比上面的解决方案干净一点;虽然我还是有点不舒服 --another opt

我试图连接3个表,其中第三个表包含对第二个表和第一个表的引用;我想要这些参考的结果。然而,在第三个表引用第一个表的地方,我不需要第二个表的结果

这很难解释,所以我已经用下面的例子说明了我想要什么

第一个select语句生成6行;我明白为什么,但那不是我想要的

第二个2给出了我想要的结果,但它们有一种代码味道。有谁能提出更好的方法来实现同样的产出

另请参见SQL Fiddle:


更新

我只是想到了另一个解决方案,感觉比上面的解决方案干净一点;虽然我还是有点不舒服

--another option; again slightly hacky

    select id, id2, id3, val, val2, val3
    from
    (
        select t1.id
        , case when t3.t1Id = t1.id then null else t2.id end id2
        , t3.id id3
        , t1.val
        , case when t3.t1Id = t1.id then null else t2.val2 end val2
        , t3.val3
        , row_number() over (partition by t1.id order by case when t3.t1Id = t1.id then null else t2.id end, t3.id) x
        from @t1 t1
        left outer join @t2 t2 
            on t2.t1Id = t1.Id
        left outer join @t3 t3
            on t3.t2Id = t2.Id
            or t3.t1Id = t1.id
    ) t
    where id2 is not null or x = 1

也许我没有完全理解您的要求/输出

但是,查询应具有相同的结果

SELECT *
FROM t3 
LEFT JOIN t2 
  ON t2.id = t3.t2Id
LEFT JOIN t1
  ON t3.t1Id = t1.id
  AND t2.id IS NULL

尝试此查询,它将生成与上次查询相同的输出结果:

SELECT T.ID, 
       CASE WHEN T3.t2Id IS NULL THEN NULL ELSE  T.T2ID END AS T2ID,
       T3.id AS T3ID,
       T.VAL, 
       CASE WHEN T3.t2Id IS NULL THEN NULL ELSE  T.VAL2 END AS VAL2,
       T3.VAL3
FROM (SELECT T1.id, 
             T1.val,
             T2.Id AS T2ID, 
             T2.val2
      FROM @t1 AS T1 JOIN @t2 AS T2 
                  ON T1.id = T2.t1id
      ) AS T JOIN @t3 AS T3 
           ON T.T2ID = T3.ID
ORDER BY  T3.VAL3

输出结果


很简单-你的错误是你的出发点。 从表3开始,左连接到其他表-然后添加一个where条件。 即


注:对于任何使用上述方法来解决问题的人来说,我发现在最现实的情况下,上述第一个有效的解决方案(即
t1 join t2 join t3
t1 join t3
的结果之间的
union all
)是最有效的。更新:迄今为止的大多数答案都建议将t3移到FROM。如果我向测试日期添加新值<代码>插入@t1(id,val)值(1,'1.1'),(8,'8.1')您将看到这种方法存在问题;i、 我们不再拥有t1中的所有值。您是否测试了您的查询?
--this works too, but feels very hacky

    select t1.id, t2.id, t3.id, t1.val, t2.val2, t3.val3
    from @t1 t1
    left outer join 
    (
        select id, t1id, val2
        from @t2

        union all

        select null, null, null

    ) t2 
        on coalesce(t2.t1Id,t1.Id) = t1.Id
    left outer join @t3 t3
        on t3.t2Id = t2.Id
        or (t3.t1Id = t1.id and t2.Id is null)
--another option; again slightly hacky

    select id, id2, id3, val, val2, val3
    from
    (
        select t1.id
        , case when t3.t1Id = t1.id then null else t2.id end id2
        , t3.id id3
        , t1.val
        , case when t3.t1Id = t1.id then null else t2.val2 end val2
        , t3.val3
        , row_number() over (partition by t1.id order by case when t3.t1Id = t1.id then null else t2.id end, t3.id) x
        from @t1 t1
        left outer join @t2 t2 
            on t2.t1Id = t1.Id
        left outer join @t3 t3
            on t3.t2Id = t2.Id
            or t3.t1Id = t1.id
    ) t
    where id2 is not null or x = 1
SELECT *
FROM t3 
LEFT JOIN t2 
  ON t2.id = t3.t2Id
LEFT JOIN t1
  ON t3.t1Id = t1.id
  AND t2.id IS NULL
SELECT T.ID, 
       CASE WHEN T3.t2Id IS NULL THEN NULL ELSE  T.T2ID END AS T2ID,
       T3.id AS T3ID,
       T.VAL, 
       CASE WHEN T3.t2Id IS NULL THEN NULL ELSE  T.VAL2 END AS VAL2,
       T3.VAL3
FROM (SELECT T1.id, 
             T1.val,
             T2.Id AS T2ID, 
             T2.val2
      FROM @t1 AS T1 JOIN @t2 AS T2 
                  ON T1.id = T2.t1id
      ) AS T JOIN @t3 AS T3 
           ON T.T2ID = T3.ID
ORDER BY  T3.VAL3
    SELECT * FROM  @t3
    LEFT OUTER JOIN @t1
    ON [@t1].id = [@t3].t1id
    LEFT OUTER JOIN @t2
    ON [@t2].id = [@t3].t2id
    WHERE [@t1].id IS NOT NULL
    OR ( [@t2].id IS NOT NULL AND [@t1].id IS NULL)