Вы можете построить динамический запрос:
DECLARE @sql NVARCHAR(MAX) =
N'SELECT *
FROM (VALUES (1)) AS s(n)
<joins>';
DECLARE @joins NVARCHAR(MAX)= '';
SELECT @joins += FORMATMESSAGE('LEFT JOIN (SELECT TOP 1 * FROM %s ) AS sub%s
ON 1=1' + CHAR(10), table_schema + '.' + table_name,
CAST(ROW_NUMBER() OVER(ORDER BY 1/0) AS VARCHAR(10)))
FROM (SELECT DISTINCT table_schema, table_name
FROM INFORMATION_SCHEMA.COLUMNS
-- WHERE ... -- custom logic based on column type/name/...
) s;
SET @sql = REPLACE(@sql, '<joins>', @joins);
PRINT @sql;
EXEC(@sql);
Демоверсия DBFiddle
Динамический запрос имеет структуру:
SELECT *
FROM (VALUES (1)) AS s(n) -- always 1 row
LEFT JOIN (SELECT TOP 1 * FROM dbo.tab1 ) AS sub1 ON 1=1 -- get single row
LEFT JOIN (SELECT TOP 1 * FROM dbo.tab2 ) AS sub2 ON 1=1
LEFT JOIN (SELECT TOP 1 * FROM dbo.tabC ) AS sub3 ON 1=1
Пожалуйста, рассматривайте это как отправную точку. Вы можете легко расширить его с условием WHERE
для каждого подзапроса и вернуть конкретные столбцы вместо *.
EDIT:
Версия с UNION ALL
:
DECLARE @sql NVARCHAR(MAX);
SELECT @sql = COALESCE(@sql + ' UNION ALL', '') +
FORMATMESSAGE(' SELECT TOP 1 tab_name=''%s'',col_name=''%s'',col_val=%s FROM %s'+CHAR(10)
,table_name, column_name, column_name, table_schema + '.' + table_name)
FROM INFORMATION_SCHEMA.COLUMNS
WHERE column_name LIKE 'colV%';
PRINT @sql;
EXEC(@sql);
DBFiddle Demo2