首页 > 解决方案 > 无法导出具有重复列的 SQL Server 大型联接查询

问题描述

我正在处理一个涉及许多连接(使用 T-SQL)的大型 SQL 查询,其中的表的列不再是唯一的连接。结果有 >600 列。有没有办法在结果列的表名前面加上它们的表名,而无需在查询的选择部分显式调用每一列,以便我可以将其导出到具有唯一列名的 CSV?

例如,我们有 28 个表,其中一些共享一个共同的列名。我无法将其导出到 csv,因为它无法知道名称相似的列之间的区别。

       TABLE 1
| columnA | columnB |

       TABLE 2
| columnC | columnB |

结果如下:

| columnA | columnB | columnC | columnB |

我无法导出结果集,因为columnB它被用作列名两次。

我希望结果集为:

| TABLE1.columnA | TABLE1.columnB | TABLE2.columnC | TABLE2.columnB |

标签: sql-servertsqlprefix

解决方案


真正做到这一点的唯一方法是使用动态 SQL 或将它们全部输入。由于您不想执行后者,因此您只能选择前者。请注意,以下是一个示例,您需要根据自己的需要修改以下内容,但是,它应该让您走上正确的道路。

USE Sandbox;
GO

CREATE TABLE Customer (ID int IDENTITY(1,1),
                       [Name] varchar(50));
CREATE TABLE Item (ID int IDENTITY(1,1),
                   [Name] varchar(50));
CREATE TABLE CustomerOrder (ID int IDENTITY(1,1),
                            ItemID int,
                            CustomerID int);
GO
INSERT INTO Customer ([Name])
VALUES ('Joe Bloggs'),('Jayne Smith');
INSERT INTO Item ([Name])
VALUES ('Spanner'),('Saw'),('Screwdriver');
INSERT INTO CustomerOrder (ItemID, CustomerID)
VALUES (1,1),(3,1),(3,1),(2,2),(3,2);
GO
SELECT *
FROM Customer C
     JOIN CustomerOrder CO ON C.ID = CO.CustomerID
     JOIN Item I ON CO.ItemID = I.ID;
GO
DECLARE @SQL nvarchar(MAX);
SET @SQL = N'SELECT ' +
           STUFF((SELECT N',' + NCHAR(10) + N'       ' + QUOTENAME(t.[name]) + N'.' + QUOTENAME(c.[name]) + N' AS ' + QUOTENAME(t.[name] + N'.' + c.[name])
                  FROM sys.columns c
                       JOIN sys.tables t ON c.object_id = t.object_id
                  WHERE t.[name] IN (N'Customer',N'Item',N'CustomerOrder')
                  FOR XML PATH(N'')),1,9,N'') + NCHAR(10) +
           N'FROM Customer' + NCHAR(10) +
           N'     JOIN CustomerOrder ON Customer.ID = CustomerOrder.CustomerID' + NCHAR(10) +
           N'     JOIN Item ON CustomerOrder.ItemID = Item.ID;';

PRINT @SQL; --Your best friend
--SELECT @SQL; --your other best friend, as I'd guess @SQL is actually going to have more than 4000 characters and PRINT can't handle that

EXEC sp_executesql @SQL;

GO
DROP TABLE Customer;
DROP TABLE Item;
DROP TABLE CustomerOrder;
GO

推荐阅读