[英]SQL Query Dynamically get columns depending on mapping
I am stuck on an issue.我被困在一个问题上。 I am trying to create a select which returns information depending on the Rules Mapping table.
我正在尝试创建一个根据规则映射表返回信息的选择。 The Rules table tells us where (TableName.ColumnName) value should come from.
规则表告诉我们 (TableName.ColumnName) 值应该从哪里来。 I have simplified the problem by just creating table variables to find a solution.
我通过创建表变量来找到解决方案来简化问题。
I have 3 tables set up.我设置了 3 个表。
The final expected result I am trying to achieve is this with the above rules is:我试图通过上述规则达到的最终预期结果是:
As you can see, I will have 3 columns in total with 3 rows (as I have 3 Main_ID).如您所见,我总共有 3 列 3 行(因为我有 3 个 Main_ID)。 Data differs depending on the @Rules table.
数据因@Rules 表而异。 For example, Header C for Main_ID 3 is showing "Address C" as the rule mapping for Header C Main_ID 3 was "@TableB.Address" which means get the information from table @TableB and column Address.
例如,Main_ID 3 的 Header C 显示“地址 C”,因为 Header C Main_ID 3 的规则映射是“@TableB.Address”,这意味着从表 @TableB 和列地址获取信息。
Here is my code for the table set up:这是我设置表格的代码:
DECLARE @TableA AS TABLE
(
Main_ID INT IDENTITY(1, 1) ,
Name VARCHAR(100)
)
INSERT INTO @TableA
VALUES ('Name A'), ('Name B'), ('Name C')
DECLARE @TableB AS TABLE
(
Secondary_ID INT IDENTITY(1, 1) ,
Main_ID INT ,
Address VARCHAR(100)
)
INSERT INTO @TableB
VALUES (1, 'Address A'), (2, 'Address B'), (3, 'Address C')
DECLARE @Rules AS TABLE
(
Rule_ID INT IDENTITY(1, 1) ,
Main_ID INT ,
Header_Name VARCHAR(100) ,
Obtain_From VARCHAR(100)
)
INSERT INTO @Rules
VALUES
-- Main_ID 1 AND 2 set up same but third one wants data from a different place.
(1, 'Header A', '@TableA.Main_ID'), (1, 'Header B', '@TableB.Address'), (1, 'Header C', '@TableA.Name'),
(2, 'Header A', '@TableA.Main_ID'), (2, 'Header B', '@TableB.Address'), (2, 'Header C', '@TableA.Name'),
(3, 'Header A', '@TableA.Main_ID'), (3, 'Header B', '@TableA.Name'), (3, 'Header C', '@TableB.Address')
SELECT * FROM @TableA
SELECT * FROM @TableB
SELECT * FROM @Rules
/*
Final result set should be:
Header A Header B Header C
1 Address A Name A
2 Address B Name B
3 Name C Address C
*/
What I have tried so far is joining the table together but there are too many rows.到目前为止,我尝试过的是将表格连接在一起,但行数太多。
Any ideas how I can achieve the final expected result?我有什么想法可以达到最终的预期结果吗?
There is a two way to do it.有两种方法可以做到。
The first way is static and easy.第一种方式是静态的并且简单。 You can use CASE expression for your mapping like that:
您可以像这样使用 CASE 表达式进行映射:
SELECT
[Header A] = CASE r_headera.Obtain_From WHEN '@TableA.Main_ID' THEN CAST(a.Main_ID AS NVARCHAR(100)) WHEN '@TableA.Name' THEN CAST(a.Name AS NVARCHAR(100)) WHEN '@TableB.Address' THEN CAST(b.Address AS NVARCHAR(100)) END,
[Header B] = CASE r_headerb.Obtain_From WHEN '@TableA.Main_ID' THEN CAST(a.Main_ID AS NVARCHAR(100)) WHEN '@TableA.Name' THEN CAST(a.Name AS NVARCHAR(100)) WHEN '@TableB.Address' THEN CAST(b.Address AS NVARCHAR(100)) END,
[Header C] = CASE r_headerc.Obtain_From WHEN '@TableA.Main_ID' THEN CAST(a.Main_ID AS NVARCHAR(100)) WHEN '@TableA.Name' THEN CAST(a.Name AS NVARCHAR(100)) WHEN '@TableB.Address' THEN CAST(b.Address AS NVARCHAR(100)) END
FROM
@TableA AS a
LEFT JOIN @TableB AS b ON b.Main_ID = a.Main_ID
LEFT JOIN @Rules AS r_headera ON r_headera.Main_ID = a.Main_ID AND r_headera.Header_Name = 'Header A'
LEFT JOIN @Rules AS r_headerb ON r_headerb.Main_ID = a.Main_ID AND r_headerb.Header_Name = 'Header B'
LEFT JOIN @Rules AS r_headerc ON r_headerc.Main_ID = a.Main_ID AND r_headerc.Header_Name = 'Header C'
Otherwise, you can use other structs such as Table Value Constructor , PIVOT , OUTER APPLY etc.否则,您可以使用其他结构,例如Table Value Constructor 、 PIVOT 、 OUTER APPLY等。
The result:结果:
Header A![]() |
Header B![]() |
Header C![]() |
---|---|---|
1 ![]() |
Address A![]() |
Name A![]() |
2 ![]() |
Address B![]() |
Name B![]() |
3 ![]() |
Name C![]() |
Address C![]() |
And the second way is Dynamic SQL with sp_executesql .第二种方法是使用sp_executesql的动态 SQL。 If you need help with that, I can prepare an example for you.
如果您需要这方面的帮助,我可以为您准备一个示例。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.