【问题标题】:Join sub tables to main table将子表连接到主表
【发布时间】:2019-02-25 10:21:06
【问题描述】:

我有三个声明的表:

  • Table_1(默认)与子 Table_2 和 Table_3 的组号相同
  • 而 Table_2 和 Table_3 的日期相同

我很难将两个子表加入到 T1 中而不会在第一次加入后丢失数据。在加入 T2 之后,T1 应该仍然有它的初始数据,而不是 NULL

我试过了:

SELECT *
FROM (
        SELECT DISTINCT * from @GRP_TABLE as T1
        FULL OUTER JOIN
        (SELECT * FROM @PASSEDBOOKINGS) AS T2
        on T1.T1_GROUP_NUMBER = T2.T2_GROUP_NUMBER  
       FULL OUTER JOIN
        (SELECT * FROM @FAILBOOKINGS)AS T3
        ON T3.T3_GROUP_NUMBER = T1.T1_GROUP_NUMBER
         and T3.T3_DATE = T2.T2_DATE
    )AS JOINS

WHERE JOINS.T3_DATE = CAST(GETDATE() AS DATE) 
OR JOINS.T2_DATE =  CAST(GETDATE() AS DATE)

@GRP_TABLE 作为 T1:

|-------|------------------|
|T1_LINE| T1_GROUP_NUMBER  | 
|-------|------------------|
|  A1   |        A110      |
|-------|------------------|
|  A1   | A120             |
|-------|------------------|
|A1     |A130              |
|-------|------------------|
|A1     |A140              |
|-------|------------------|
|A1     |A150              |
|-------|------------------|

@PASSEDBOOKING 作为 T2:

|---------------|-----------|----------|
|T2_GROUP_NUMBER| T2_COUNTS | T2_DATE  |
|---------------|-----------|----------|
|  A110         | 2         |2019-02-25|
|---------------|-----------|----------|
|  A120         | 2         |2019-02-25|
|---------------|-----------|----------|
|A130           |2          |2019-02-25|
|---------------|-----------|----------|

@FAILEDBOOKINGS 作为 T3:

|---------------|-----------|----------|
|T3_GROUP_NUMBER| T3_COUNTS | T3_DATE  |
|---------------|-----------|----------|
|  A140         | 1         |2019-02-25|
|---------------|-----------|----------|
|  A150         | 1         |2019-02-25|
|---------------|-----------|----------|

这会导致:

|-------|------------------|------------------|----------|-----------------|-------------|------------------|------------------|
|T1_LINE| T1_GROUP_NUMBER  | T2_GROUP_NUMBER  |T2_COUNTS | T3_GROUP_NUMBER |T3_COUNTS    |      T2_DATE     | T3_DATE          |
|-------|------------------|------------------|----------|-----------------|-------------|------------------|------------------|
|  NULL |        NULL      |        NULL      |     NULL |  A140           |       1     |      NULL        |   2019-02-25     |
|-------|------------------|------------------|----------|-----------------|-------------|------------------|------------------|
|  NULL | NULL             |          NULL    | NULL     |A150             |        1    |      NULL        |   2019-02-25     |
|-------|------------------|------------------|----------|-----------------|-------------|------------------|------------------|
|A1     |A110              |    A110          |     2    |      NULL       |    NULL     |      2019-02-25  |   NULL           |
|-------|------------------|------------------|----------|-----------------|-------------|------------------|------------------|
|A1     |A120              |    A120          |     2    |      NULL       |    NULL     |      2019-02-25  |   NULL           |
|-------|------------------|------------------|----------|-----------------|-------------|------------------|------------------|
|A1     |A130              |    A130          |     2    |      NULL       |    NULL     |      2019-02-25  |       NULL       |
|-------|------------------|------------------|----------|-----------------|-------------|------------------|------------------|

但我期待这些结果:

|-------|------------------|------------------|----------|-----------------|-------------|------------------|------------------|
|T1_LINE| T1_GROUP_NUMBER  | T2_GROUP_NUMBER  |T2_COUNTS | T3_GROUP_NUMBER |T3_COUNTS    |      T2_DATE     | T3_DATE          |
|-------|------------------|------------------|----------|-----------------|-------------|------------------|------------------|
|  A1   |        A140      |        NULL      |     NULL |  A140           |       1     |      NULL        |   2019-02-25     |
|-------|------------------|------------------|----------|-----------------|-------------|------------------|------------------|
|  A1   | A150             |          NULL    | NULL     |A150             |        1    |      NULL        |   2019-02-25     |
|-------|------------------|------------------|----------|-----------------|-------------|------------------|------------------|
|A1     |A110              |    A110          |     2    |      NULL       |    NULL     |      2019-02-25  |   NULL           |
|-------|------------------|------------------|----------|-----------------|-------------|------------------|------------------|
|A1     |A120              |    A120          |     2    |      NULL       |    NULL     |      2019-02-25  |   NULL           |
|-------|------------------|------------------|----------|-----------------|-------------|------------------|------------------|
|A1     |A130              |    A130          |     2    |      NULL       |    NULL     |      2019-02-25  |       NULL       |
|-------|------------------|------------------|----------|-----------------|-------------|------------------|------------------|

【问题讨论】:

  • 你能发布一些示例数据吗?您得到的结果很有帮助,但它们并没有向我们展示您的数据在之前您的查询之后是什么样子,只有在之后。确保样本数据代表您在上面提供的数据。谢谢。
  • @Larnu 谢谢,查看更新。
  • 我看到你所有的 sql 都在@-tables:也许你可以把你的例子放在a rexter wall 上?
  • 不幸被公司屏蔽 :( @AlexYu

标签: sql sql-server


【解决方案1】:

您可以尝试使用 COALESCE 函数 - 因此,如果一个表中不存在数据,请从另一个表中获取它

谢谢

【讨论】:

    【解决方案2】:

    空输出的原因

    1. 即使 T1 表包含 A140 和 A150,那么对应的 T2 和 T3 日期也不相同,实际上这些日期在您的示例数据中并不存在。

    要获得您提到的预期输出,您可以执行以下操作,

    SELECT *
    From
     @GRP_TABLE as T1
    Left JOIN
     @PASSEDBOOKINGS AS T2
    on T1.T1_GROUP_NUMBER = T2.T2_GROUP_NUMBER  
    Left JOIN
    @FAILBOOKINGS AS T3
            ON T3.T3_GROUP_NUMBER = T1.T1_GROUP_NUMBER
    WHERE T3.T3_DATE = CAST(GETDATE() AS DATE) 
    OR T2.T2_DATE =  CAST(GETDATE() AS DATE)
    

    【讨论】:

      【解决方案3】:

      查看您的数据似乎需要左连接

      SELECT DISTINCT T1.T1_LINE, T1.T1_GROUP_NUMBER
          ,  T2.T2_GROUP_NUMBER , T2.T2_COUNT
          , T3.T3_GROUP_NUMBER, T2.T2_COUNTS,  T2.T2_DATE, T3.T3_DATE, T3.T3_COUNT 
      from @GRP_TABLE T1 
      LEFT JOIN @PASSEDBOOKING T2 ON T1.T1_GROUP_NUMBER = T2.T2_GROUP_NUMBER 
      LEFT JOIN @FAILEDBOOKINGS AS T3  ON T1.T1_GROUP_NUMBER = T3.T2_GROUP_NUMBER  
      

      【讨论】:

        【解决方案4】:

        FULL OUTER JOIN 非常昂贵,我看不出有什么理由在这里使用它。您有一个始终希望返回数据的主表和两个辅助表 - 这是 FROM T1 LEFT JOIN T2, T3...的经典案例...

        请考虑这个。

            SELECT *
        FROM @GRP_TABLE as T1
        LEFT JOIN @PASSEDBOOKINGS AS T2
                on T1.T1_GROUP_NUMBER = T2.T2_GROUP_NUMBER  
                and T2.T2_DATE =  CAST(GETDATE() AS DATE)
        LEFT JOIN  @FAILBOOKINGS AS T3
                ON T3.T3_GROUP_NUMBER = T1.T1_GROUP_NUMBER
                 and T3.T3_DATE = T2.T2_DATE
        

        我什至不确定您是否必须加入 date to date,因为无论如何这两个表都仅限于一个日期。:

        SELECT *
        FROM @GRP_TABLE as T1
        LEFT JOIN @PASSEDBOOKINGS AS T2
                on T1.T1_GROUP_NUMBER = T2.T2_GROUP_NUMBER  
                and T2.T2_DATE =  CAST(GETDATE() AS DATE)
        LEFT JOIN  @FAILBOOKINGS AS T3
                ON T3.T3_GROUP_NUMBER = T1.T1_GROUP_NUMBER
                 and T3.T3_DATE = CAST(GETDATE() AS DATE)
        

        还可以考虑合并 T2 和 T3,可能更有意义!

        SELECT *
        FROM @GRP_TABLE as T1
        LEFT JOIN (SELECT 'pass' as type, * FROM @PASSEDBOOKINGS WHERE DATE = CAST(GETDATE() AS DATE
                        UNION
                    SELECT 'fail' as type, * FROM @FAILBOOKINGS WHERE DATE = CAST(GETDATE() AS DATE
                    ) 
                    T2 on T2.GROUP_NUMBER = T1.GROUP_NUMBER  
        

        【讨论】:

        • 谢谢,添加日期条件只是为了限制数据,有3周前的数据,这就是我加入日期的原因。
        • LEFT JOIN 只返回第一个绑定表即T2数据
        • 只要 groupnumber 在 t1 上,T2 和 T3 都会返回行。在这种情况下,您将 T3 限制在 T2 上的日期 - 这是故意设计吗?
        • 是的,它们在脚本的其他地方使用。有人建议Coalesce,它给出了与我预期相似的结果,所以我将使用它。谢谢:)
        猜你喜欢
        • 2013-11-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-01-29
        • 1970-01-01
        • 2015-01-08
        • 1970-01-01
        • 2023-03-22
        相关资源
        最近更新 更多