You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

TSQL 如何从记录集动态生成多表关联SELECT查询语句

实现方案

方案1:SQL Server 2017及以上版本(推荐,使用STRING_AGG)

这个版本原生支持字符串聚合函数,逻辑更简洁易读,生成结果和预期完全一致:

SELECT 
    PSchemaName,
    PTableName,
    FSchemaName,
    FTableName,
    CONCAT(
        'SELECT ',
        -- 拼接所有从表查询字段
        STRING_AGG(CONCAT('[F].[', FColumnName, ']'), ', ') WITHIN GROUP (ORDER BY ColumnOrder),
        ', ',
        -- 拼接所有主表查询字段
        STRING_AGG(CONCAT('[P].[', PColumnName, ']'), ', ') WITHIN GROUP (ORDER BY ColumnOrder),
        ' FROM [', FSchemaName, '].[', FTableName, '] AS [F] JOIN [', PSchemaName, '].[', PTableName, '] AS [P] ON ',
        -- 拼接关联条件
        STRING_AGG(CONCAT('[P].[', PColumnName, '] = [F].[', FColumnName, ']'), ' AND ') WITHIN GROUP (ORDER BY ColumnOrder),
        ' ;'
    ) AS CMD
FROM @Tbl_List
GROUP BY PSchemaName, PTableName, FSchemaName, FTableName
ORDER BY PSchemaName, PTableName, FSchemaName, FTableName

方案2:SQL Server 2016及更低版本(兼容旧版本,使用FOR XML PATH)

如果你使用的是不支持STRING_AGG的旧版本SQL Server,可以用经典的FOR XML拼接方案:

SELECT 
    main.PSchemaName,
    main.PTableName,
    main.FSchemaName,
    main.FTableName,
    CONCAT(
        'SELECT ',
        -- 拼接所有从表字段
        STUFF((
            SELECT CONCAT(', [F].[', FColumnName, ']')
            FROM @Tbl_List sub
            WHERE sub.PSchemaName = main.PSchemaName 
                AND sub.PTableName = main.PTableName 
                AND sub.FSchemaName = main.FSchemaName 
                AND sub.FTableName = main.FTableName
            ORDER BY sub.ColumnOrder
            FOR XML PATH(''), TYPE
        ).value('.', 'NVARCHAR(MAX)'), 1, 2, ''),
        ', ',
        -- 拼接所有主表字段
        STUFF((
            SELECT CONCAT(', [P].[', PColumnName, ']')
            FROM @Tbl_List sub
            WHERE sub.PSchemaName = main.PSchemaName 
                AND sub.PTableName = main.PTableName 
                AND sub.FSchemaName = main.FSchemaName 
                AND sub.FTableName = main.FTableName
            ORDER BY sub.ColumnOrder
            FOR XML PATH(''), TYPE
        ).value('.', 'NVARCHAR(MAX)'), 1, 2, ''),
        ' FROM [', main.FSchemaName, '].[', main.FTableName, '] AS [F] JOIN [', main.PSchemaName, '].[', main.PTableName, '] AS [P] ON ',
        -- 拼接关联条件
        STUFF((
            SELECT CONCAT(' AND [P].[', PColumnName, '] = [F].[', FColumnName, ']')
            FROM @Tbl_List sub
            WHERE sub.PSchemaName = main.PSchemaName 
                AND sub.PTableName = main.PTableName 
                AND sub.FSchemaName = main.FSchemaName 
                AND sub.FTableName = main.FTableName
            ORDER BY sub.ColumnOrder
            FOR XML PATH(''), TYPE
        ).value('.', 'NVARCHAR(MAX)'), 1, 5, ''),
        ' ;'
    ) AS CMD
FROM @Tbl_List main
GROUP BY main.PSchemaName, main.PTableName, main.FSchemaName, main.FTableName
ORDER BY main.PSchemaName, main.PTableName, main.FSchemaName, main.FTableName

实现原理说明

  • 拼接=符号:单条关联规则直接按照[P].[{PColumnName}] = [F].[{FColumnName}]的固定格式拼接即可,每条记录生成一个完整的相等判断条件,不需要额外处理。
  • 多条件自动加AND:
    • 用STRING_AGG时直接指定分隔符为AND,聚合函数会自动在多个条件之间插入分隔符,首尾不会产生多余的连接符。
    • 用FOR XML PATH时,子查询返回的每个条件前都拼接AND,最后用STUFF函数删除开头多余的5个字符(也就是第一个多余的AND),即可得到正确的条件串。
  • 顺序控制:两种方案都通过ColumnOrder字段排序,保证字段选择、关联条件的顺序完全符合要求。

注:你提供的预期输出最后一行存在两处笔误,从表empdtl4被误写为empdtl3,主表emphdr3被误写为emphdr4,上述代码生成的结果会自动修正该问题。

内容的提问来源于stack exchange,提问作者007

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 03:06:03