【问题标题】:Create dynamic inner join with multiple column on SQL SERVER在 SQL SERVER 上创建具有多列的动态内部联接
【发布时间】:2020-09-24 22:58:22
【问题描述】:

我想创建一个内部连接的动态查询。

我有一个带有列名的临时表 #table2

| ColumnName  |
---------------
| column1     |
| column2     |
| column3     |

我的查询应该如下所示:

SELECT * FROM table1 t1
INNER JOIN #table2 t2 ON t2.column1 = t1.column1 AND t2.column2 = t1.column2.......

问题是我事先不知道我的 temp #table2 中有多少列,所以我必须能够添加:

  AND t2.column4 = ....
  AND t2.column5 = ....

感谢您的帮助

【问题讨论】:

  • 您好,我认为您可以使用 (string_agg / concat into variable 和 Exec commande) 来构建您的动态。请提供您的 SQL 服务器版本 string_agg 在旧版本中不受支持。 sqlservertutorial.net/sql-server-string-functions/…
  • 修复你的数据模型!不知道一张表中有多少列只会让你的生活变得非常困难。
  • SQL SERVER 2012 @GordonLinoff 不是我选择多少列。我无法更改该模型
  • SQL SERVER 2012 @Sanpas
  • @Sanpas ,不,他们不能。 STRING_AGG 在 SQL Server 2017 中添加...您链接到的文档甚至指出:适用于:✓ SQL Server 2017 (14.x) 及更高版本"

标签: sql sql-server


【解决方案1】:

#TempTable 列可以通过查询 tempdb.sys.columns 找到。 所以你可以像下面这样写动态sql...

IF OBJECT_ID('tempdb..#TempTable', 'U') IS NOT NULL 
BEGIN DROP TABLE #TempTable; END;

CREATE TABLE #TempTable (
    Column_1 int NOT NULL,
    Column_2 int NOT NULL,
    Column_3 int NOT NULL 
    );

--============================================================

DECLARE @sql nvarchar(MAX) = N'';
SELECT 
    @sql = CONCAT(@sql, N'
        AND t1.', c.name, N' = t2.', c.name)
FROM
    tempdb.sys.columns c
WHERE 
    c.object_id = OBJECT_ID('tempdb..#TempTable');

SELECT 
    @sql = CONCAT(N'
SELECT 
    * 
FROM 
    dbo.table1 t1
    INNER JOIN #table2 t2 
        ON', STUFF(@sql, 1, 7, N''), N';');

PRINT(@sql);

上述查询的输出...

SELECT 
    * 
FROM 
    dbo.table1 t1
    INNER JOIN #table2 t2 
        ON t1.Column_1 = t2.Column_1
        AND t1.Column_2 = t2.Column_2
        AND t1.Column_3 = t2.Column_3;

【讨论】:

    【解决方案2】:

    你可以试试FOR XML PATH:

    DECLARE @TabName1 NVARCHAR(100) = '#Tab1';
    DECLARE @TabName2 NVARCHAR(100) = '#Tab2';
    
    DECLARE @stmt NVARCHAR(4000) = 'SELECT * FROM ' + @TabName1 + ' INNER JOIN ' + @TabName2 + ' ON ';
    
    WITH cte AS(
    SELECT @TabName1 + '.' + ac.name + ' = ' + @TabName2 + '.' + ac2.name as stmtJoin
      FROM tempdb.sys.objects o
      JOIN tempdb.sys.all_columns ac ON ac.object_id = o.object_id
      JOIN tempdb.sys.all_columns ac2 ON ac2.object_id = OBJECT_ID(N'tempdb..' + @TabName2) AND ac.column_id = ac2.column_id
      WHERE o.OBJECT_ID = OBJECT_ID(N'tempdb..' + @TabName1)
    ),
    cteStmt AS(
    SELECT DISTINCT (SELECT stmtJoin + ' AND '
      FROM cte
      FOR XML PATH('')) cols
      FROM cte
    )
    SELECT @stmt = @stmt + SUBSTRING(cols, 1, LEN(cols)-4)
      FROM cteStmt
    
    EXEC(@stmt)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-12-08
      • 2013-11-17
      • 1970-01-01
      • 2020-10-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多