【问题标题】:SQL combining multiple tables into one issueSQL将多个表合并为一个问题
【发布时间】:2021-03-11 04:15:21
【问题描述】:

我在 SSMS 中运行以下查询,您可以看到它显示了来自不同数据库的多个表中的结果。

如何将表格合并为一个?

我尝试将 UNION 和 UNION ALL 添加到 SELECT @Sql = COALESCE(@Sql + ' UNION ' + CHAR(13) + CHAR(10), '' ) + 中,但出现 Cannot resolve the collation conflict between "Latin1_General_CI_AS" and "SQL_Latin1_General_CP1_CI_AS" in the UNION operation. 错误

任何想法将不胜感激!

DECLARE @table table(dbname sysname COLLATE Latin1_General_CI_AS)

INSERT INTO @table(dbname)
SELECT NAME COLLATE Latin1_General_CI_AS FROM sys.databases where name like '%AccountsLive'

DECLARE @Sql NVARCHAR(MAX) = NULL;

SELECT  @Sql = COALESCE(@Sql + CHAR(13) + CHAR(10), '' ) +
'SELECT c_broker, det_costheader, cuname, ch_name, CONVERT(VARCHAR(11),ch_date_req,103) AS ''Flight_Date'', IIF(OUT.outstanding>0, ''Yes'', ''No'') AS ''Anything_Outstanding?'', sum(c_grossmargin)/2 AS ''Gross_Margin'' FROM ' 
+ QUOTENAME(dbname) COLLATE Latin1_General_CI_AS + '.dbo.AT_ACS_COMMISSIONS AS COM
LEFT JOIN ' + QUOTENAME(dbname) COLLATE Latin1_General_CI_AS + '.dbo.AT_ACS_PROJECTOUTSTANDING AS OUT
ON COM.det_costheader = OUT.project
WHERE c_broker = ''HKGCGOJT''
GROUP BY det_costheader, c_broker, cuname, ch_name, ch_date_req, outstanding'
FROM    @table

exec( @Sql );

【问题讨论】:

  • 将您的 sql 复制到您的问题的文本中,并在有人可以帮助您之前很好地格式化它
  • 对不起 - 我认为图片会更好......我已经编辑它现在以文本形式显示代码
  • 请添加第二个您想要联合的查询。
  • @KaziMohammadAliNur - 没有第二个查询,只有这个。当我运行此查询时,它会根据数据库将结果生成到单个表中。我只想为这个查询生成一个表......这可能吗?
  • 将结果插入到临时表中

标签: sql-server ssms


【解决方案1】:

如果任何列在不同数据库中有不同的排序规则,那么您需要向它们添加COLLATE。我添加了几个来向您展示它是如何完成的。

注意事项:

  • 这里不需要表变量
  • 使用STRING_AGG(或FOR XML)进行聚合,do not use variable coalescingit is unsafe
  • 如果你打算添加参数,那么使用sp_executesql并将参数传递给动态部分。 不要将参数连接到查询中。
DECLARE @Sql NVARCHAR(MAX);
SET @Sql =
(SELECT
    STRING_AGG(

N'SELECT
    c_broker COLLATE Latin1_General_CI_AS,
    det_costheader,
    cuname COLLATE Latin1_General_CI_AS,
    ch_name,
    CONVERT(VARCHAR(11), ch_date_req, 103) AS [Flight_Date],
    IIF(OUT.outstanding > 0, ''Yes'', ''No'') AS [Anything_Outstanding?],
    sum(c_grossmargin) / 2 AS [Gross_Margin]
FROM ' + QUOTENAME(d.name) + N'.dbo.AT_ACS_COMMISSIONS AS COM
LEFT JOIN ' + QUOTENAME(d.name) + N'.dbo.AT_ACS_PROJECTOUTSTANDING AS OUT
ON COM.det_costheader = OUT.project
WHERE c_broker = ''HKGCGOJT''
GROUP BY det_costheader, c_broker, cuname, ch_name, ch_date_req, outstanding
',
    CAST (N'
UNION ALL
' AS nvarchar(max)) )

FROM sys.databases d
where name like '%AccountsLive'
);

exec( @Sql );

如果您使用的是没有STRING_AGG 的旧版SQL Server,则需要使用FOR XML 进行聚合:

DECLARE @Sql NVARCHAR(MAX);
SET @Sql =
STUFF(
(SELECT
    NCHAR(10) + N'UNION ALL' + NCHAR(10) +
N'SELECT
    c_broker COLLATE Latin1_General_CI_AS,
    det_costheader,
    cuname COLLATE Latin1_General_CI_AS,
    ch_name,
    CONVERT(VARCHAR(11), ch_date_req, 103) AS [Flight_Date],
    IIF(OUT.outstanding > 0, ''Yes'', ''No'') AS [Anything_Outstanding?],
    sum(c_grossmargin) / 2 AS [Gross_Margin]
FROM ' + QUOTENAME(d.name) + N'.dbo.AT_ACS_COMMISSIONS AS COM
LEFT JOIN ' + QUOTENAME(d.name) + N'.dbo.AT_ACS_PROJECTOUTSTANDING AS OUT
ON COM.det_costheader = OUT.project
WHERE c_broker = ''HKGCGOJT''
GROUP BY det_costheader, c_broker, cuname, ch_name, ch_date_req, outstanding
'
FROM sys.databases d
where name like '%AccountsLive'
FOR XML PATH(''), TYPE)

.value('text()[1]','nvarchar(max)'), 1, 11, '');

exec( @Sql );

我建议使用PRINT @Sql 进行测试,以确保生成的 SQL 确实有效。

【讨论】:

  • 感谢@Charlieface 的帮助 - 但是,我在 SSMS 中收到了 STRING_AGG is not a recognised built-in function name?另外,must declare the scaler variable "@SQL"...?
  • 感谢@Charlieface 提供的所有帮助,非常感谢.....最后一个问题(希望如此)是 UNION 附近的语法错误?
  • 当我复制你的时,哎呀,无关;。用print @Sql检查一下
  • 你是我的英雄!感谢您的帮助!
猜你喜欢
  • 2022-01-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-07-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-03-27
相关资源
最近更新 更多