使用 SQL & T-SQL 连接多个表
Join multiple tables using SQL & T-SQL
不幸的是,我不能确定我的问题名称在这里是正确的。
初始数据示例:
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 |
在我的初始数据中,我有 3 table 字段 ID
之间的关系。
我需要将 table2
和 table3
连接到第一个 table,但是如果我进行顺序连接,例如 left join table2
和 left join table3
ID
我会在第二次加入时获得额外的记录,因为第一次加入后会有几条记录具有一个ID。
我需要获取 table2
和 table3
的记录,例如第一个 table.
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 |
这是我会使用的方法,但是,您的 table 设计可能还可以改进;为什么 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 行,那么您可以即时构建一个 "proper" 计数 table,或者创建一个物理计数。一个即时的可能会是一个更好的主意,因为我怀疑你会有 100 的匹配行。
不幸的是,我不能确定我的问题名称在这里是正确的。
初始数据示例:
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 |
在我的初始数据中,我有 3 table 字段 ID
之间的关系。
我需要将 table2
和 table3
连接到第一个 table,但是如果我进行顺序连接,例如 left join table2
和 left join table3
ID
我会在第二次加入时获得额外的记录,因为第一次加入后会有几条记录具有一个ID。
我需要获取 table2
和 table3
的记录,例如第一个 table.
这里是预期结果的示例:
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 |
这是我会使用的方法,但是,您的 table 设计可能还可以改进;为什么 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 行,那么您可以即时构建一个 "proper" 计数 table,或者创建一个物理计数。一个即时的可能会是一个更好的主意,因为我怀疑你会有 100 的匹配行。