我的任务是从另一个不是我设计的数据库中获取一些数据,因此设计不能改变。
查看数据我需要根据另一个表中保存的值动态加入表。
E.G
SELECT * FROM TableA LEFT JOIN TableB oN TableA.TBID = TableB.ID LEFT JOIN TableB.TableOffset AS C ON C.TableAID = TableA.ID
因此,表B有一个名为TableOffset的列,它包含需要作为C连接的表的名称
(我试过做一个SQLFIDDLE,但该网站没有使用SQL Server ATM)
问题是数据可能有112个属性表,因此对每个属性表进行左连接会减慢我想象的查询速度。
所以基于下面我需要得到一个结果集:
| TableAID | TableATitle | AttrTableA21 | AttrTableA22 |
|----------|-------------|--------------|--------------|
|1 |test | Name | 2019 |
|2 |test2 | Name 2 | 2016 |
示例SQL代码
CREATE TABLE [dbo].[TableA](
[ID] [int] NOT NULL,
[Title] [nvarchar](100) NOT NULL,
[TableBID] [int] NOT NULL
);
CREATE TABLE [dbo].[TableB](
[ID] [int] NOT NULL,
[TableName] [nvarchar](100) NOT NULL
);
CREATE TABLE [dbo].[ATTR_A](
[ID] [int] NOT NULL,
[TableAID] [int] NOT NULL,
[A21] [nvarchar](100) NOT NULL,
[A22] [int] NOT NULL
);
CREATE TABLE [dbo].[ATTR_B](
[ID] [int] NOT NULL,
[TableAID] [int] NOT NULL,
[A21] [nvarchar](100) NOT NULL,
[A22] [int] NOT NULL
);
CREATE TABLE [dbo].[ATTR_C](
[ID] [int] NOT NULL,
[TableAID] [int] NOT NULL,
[A21] [nvarchar](100) NOT NULL,
[A22] [int] NOT NULL
);
CREATE TABLE [dbo].[ATTR_D](
[ID] [int] NOT NULL,
[TableAID] [int] NOT NULL,
[A21] [nvarchar](100) NOT NULL,
[A22] [int] NOT NULL
);
INSERT INTO TableA VALUES(1, 'test', 1);
INSERT INTO TableB VALUES(1, 'ATTR_C');
INSERT INTO ATTR_C VALUES (1, 1, 'Name', 2019);
INSERT INTO TableA VALUES(2, 'test2', 2);
INSERT INTO TableB VALUES (2, 'ATTR_A');
INSERT INTO ATTR_A VALUES (1, 2, 'Name 2', 2016);
```
你已经被告知,这种方法完全是错误的。但如果你必须坚持这一点,你可以试试这个:
您在新数据库中的测试场景(仔细,如果您已经使用此数据库名称......)
USE master;
GO
CREATE DATABASE MyTestDb;
GO
USE MyTestDb;
GO
CREATE TABLE [dbo].[TableA](
[ID] [int] NOT NULL,
[Title] [nvarchar](100) NOT NULL,
[TableBID] [int] NOT NULL
);
CREATE TABLE [dbo].[TableB](
[ID] [int] NOT NULL,
[TableName] [nvarchar](100) NOT NULL
);
CREATE TABLE [dbo].[ATTR_A](
[ID] [int] NOT NULL,
[TableAID] [int] NOT NULL,
[A21] [nvarchar](100) NOT NULL,
[A22] [int] NOT NULL
);
CREATE TABLE [dbo].[ATTR_B](
[ID] [int] NOT NULL,
[TableAID] [int] NOT NULL,
[A21] [nvarchar](100) NOT NULL,
[A22] [int] NOT NULL
);
CREATE TABLE [dbo].[ATTR_C](
[ID] [int] NOT NULL,
[TableAID] [int] NOT NULL,
[A21] [nvarchar](100) NOT NULL,
[A22] [int] NOT NULL
);
CREATE TABLE [dbo].[ATTR_D](
[ID] [int] NOT NULL,
[TableAID] [int] NOT NULL,
[A21] [nvarchar](100) NOT NULL,
[A22] [int] NOT NULL
);
INSERT INTO TableA VALUES(1, 'test', 1);
INSERT INTO TableB VALUES(1, 'ATTR_C');
INSERT INTO ATTR_C VALUES (1, 1, 'Name', 2019);
INSERT INTO TableA VALUES(2, 'test2', 2);
INSERT INTO TableB VALUES (2, 'ATTR_A');
INSERT INTO ATTR_A VALUES (1, 2, 'Name 2', 2016);
GO
- 我创建了一个内联表值函数,其中所有属性表都使用UNION ALL
作为一组返回
- 如果参数不合适,引擎足够智能,以避免呼叫。
CREATE FUNCTION dbo.GetTheRightSet(@SetKey VARCHAR(10))
RETURNS TABLE
AS
RETURN
SELECT ID,TableAID,A21,A22 FROM dbo.ATTR_A WHERE @SetKey='ATTR_A'
UNION ALL
SELECT ID,TableAID,A21,A22 FROM dbo.ATTR_B WHERE @SetKey='ATTR_B'
UNION ALL
SELECT ID,TableAID,A21,A22 FROM dbo.ATTR_C WHERE @SetKey='ATTR_C'
UNION ALL
SELECT ID,TableAID,A21,A22 FROM dbo.ATTR_D WHERE @SetKey='ATTR_D'
GO
- 这是如何使用它
SELECT TableA.*
,TableB.*
,TheSet.*
FROM TableA
LEFT JOIN TableB ON TableA.TableBID = TableB.ID
OUTER APPLY dbo.GetTheRightSet(TableB.TableName) TheSet
GO
- 清理(小心实际数据)
USE master;
GO
DROP DATABASE MyTestDb;