【问题标题】:Join multiple tables using SQL & T-SQL使用 SQL 和 T-SQL 连接多个表
【发布时间】:2018-11-05 15:14:29
【问题描述】:

很遗憾,我无法确定我的问题名称是否正确。

初始数据示例:

Table 1           Table 2           Table 3
| ID | Name  |    | ID | Info1 |    | ID | Info2 |
|----|-------|    |----|-------|    |----|-------|
| 1  | Name1 |    | 1  | text1 |    | 1  | text1 |
| 2  | Name2 |    | 1  | text1 |    | 1  | text1 |
| 3  | Name3 |    | 2  | text2 |    | 1  | text1 |
                  | 2  | text2 |    | 2  | text2 |
                                    | 3  | text3 |

在我的初始数据中,我通过字段ID 在 3 个表之间建立了关系。

我需要将table2table3 加入到第一个表中,但是如果我进行顺序加入,例如left join table2left join table3 by ID,我将在第二次加入时获得额外的记录,因为会有是第一次加入后具有一个 ID 的多条记录。

我需要获取table2table3 的记录,就像每列中第一个表ID 的列表一样。

这里是预期结果的示例:

 Table 3
|  ID   |   Name    |Info1(Table2)|Info2(Table3)|
|-------|-----------|-------------|-------------|
|  1    |   Name1   |    text1    |    text1    |
|  1    |   Name1   |    text1    |    text1    |
|  1    |   Name1   |    null     |    text1    |
|  2    |   Name2   |    text2    |    text2    |
|  2    |   Name2   |    text2    |    null     |
|  3    |   Name3   |    null     |    text3    |

【问题讨论】:

  • 你试过Inner join吗?

标签: sql sql-server tsql sql-server-2017


【解决方案1】:

这是我会使用的方法,但是,您的表格设计可能会有所改进;为什么Table2和Table3首先是分开的?

USE Sandbox;
GO

CREATE TABLE dbo.Table1 (ID int, [Name] varchar(5))
INSERT INTO dbo.Table1 (ID,
                        [Name])
VALUES(1,'Name1'),
      (2,'Name1'),
      (3,'Name3');

CREATE TABLE dbo.Table2 (Id int,Info1 varchar(5));
CREATE TABLE dbo.Table3 (Id int,Info2 varchar(5));

INSERT INTO dbo.Table2 (Id,
                    Info1)
VALUES(1,'text1'),
      (1,'text1'),
      (2,'text2'),
      (2,'text2');
INSERT INTO dbo.Table3 (Id,
                        Info2)
VALUES(1,'text1'),
      (1,'text1'),
      (1,'text1'),
      (2,'text2'),
      (3,'text3');


WITH T2 AS(
    SELECT ID,
           Info1,
           ROW_NUMBER() OVER (PARTITION BY ID ORDER BY (SELECT NULL)) AS RN --SELECT NULL as you have no other columns to actually create an order
    FROM Table2),
T3 AS(
    SELECT ID,
           Info2,
           ROW_NUMBER() OVER (PARTITION BY ID ORDER BY (SELECT NULL)) AS RN
    FROM Table3),
Tally AS(
    SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS I --Assuming you have 10 or less matching items
    FROM (VALUES(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL)) N(N))
SELECT T1.ID,
       T1.[Name],
       T2.info1,
       T3.info2
FROM Table1 T1
     CROSS JOIN Tally T
     LEFT JOIN T2 ON T1.ID = T2.ID AND T.I = T2.RN
     LEFT JOIN T3 ON T1.ID = T3.ID AND T.I = T3.RN
WHERE T2.ID IS NOT NULL OR T3.ID IS NOT NULL
ORDER BY T1.ID, T.I;


GO

DROP TABLE dbo.Table1;
DROP TABLE dbo.Table2;
DROP TABLE dbo.Table3;

如果您的行数超过 10 行,那么您可以即时构建一个“适当的”计数表,或者创建一个物理表。不过,动态的可能会是一个更好的主意,因为我怀疑你会有 100 个匹配的行。

【讨论】:

  • @TimBiegeleisen 修复了,我傻了,把T.I = T2.RN 排除在外 >_(在我创建了计数表之后,这非常愚蠢)
猜你喜欢
  • 2017-09-18
  • 1970-01-01
  • 1970-01-01
  • 2017-09-18
  • 1970-01-01
  • 1970-01-01
  • 2018-12-12
  • 2020-10-11
  • 1970-01-01
相关资源
最近更新 更多