每个数据库的单个结果和按数据库分组的结果
Single result for each database and group results by database
大家好,我是 SQL 的业余爱好者,但我花了几个小时寻找如何做到这一点,据我所知,没有人描述过它(至少没有说到点子上)我能理解)。
我有一个 SQL 查询,我需要 运行 针对我服务器上的 45 个(非系统)数据库中的每一个:
SELECT TOP 1 IdTransaction, IdDateTime, ArchivedDate, RetentionCategoryIdentity
FROM Saveset
WHERE NOT EXISTS (
SELECT * FROM HoldSaveset
WHERE saveset.SavesetIdentity = HoldSaveset.SavesetIdentity)
由于此查询只有 returns 个结果,我想按数据库名称对这些结果进行分组。如果它能让事情变得更简单,我只是 真正 对 "ArchivedDate" 感兴趣。
您可以使用动态 SQL 创建您的 select 语句。只需将您想要的 table 名称放入 @targetTable 变量中。它将创建一个 table 来存储您的结果。希望这可以帮助!如果您有任何问题,请告诉我!
DECLARE @sql VARCHAR(MAX),
@targetTable VARCHAR(100);
SELECT @sql = 'select top 1 IdTransaction, IdDateTime, ArchivedDate, RetentionCategoryIdentity ' +
'FROM '+ QUOTENAME(name) + '.dbo.Saveset AS A '
+ 'where NOT exists (Select * from ' + QUOTENAME(name) + '.dbo.HoldSaveset AS B ' + 'WHERE A.SavesetIdentity = B.SavesetIdentity) UNION ALL ' + COALESCE(@sql,'')
FROM master..sysdatabases
WHERE NAME NOT IN('master','tempdb','model','msdb')
SET @targetTable = 'database.schema.tablename'
SELECT @sql = 'SELECT * INTO ' + @targetTable + ' FROM (' + SUBSTRING(@sql,0,LEN(@SQL) -8) + ') A';
EXEC (@sql)
您可以查询 sys.databases,在 NAME 字段上使用某种过滤器,将您想要的所有数据库名称插入到 Table 变量中。包含一个可用于循环的顺序字段。该代码看起来像这样。
DECLARE @MyDatabases TABLE (DbName VARCHAR(500), RowNum INT IDENTITY(1,1))
INSERT INTO @MyDatabases (DbName)
SELECT name
FROM sys.databases
WHERE name LIKE '%filter names here%'
一旦您想要的数据库在 Table 变量中,您可以遍历 table,在 Table 中为每个数据库执行一次动态 SQL 语句变量并将结果插入临时 table。循环完成后,您可以 select 临时 table 中的所有值作为最终结果。执行此操作的代码如下所示。
CREATE TABLE #MyData (ArchivedDate VARCHAR(100), DbName VARCHAR(500))
DECLARE @CurrentDatabase VARCHAR(500)
DECLARE @SQL VARCHAR(MAX)
DECLARE @Counter INT = 1
WHILE @Counter <= (SELECT MAX(RowNum) FROM @MyDatabases)
BEGIN
SELECT @CurrentDatabase = DbName
FROM @MyDatabases
WHERE RowNum = @Counter
SET @SQL = 'INSERT INTO #MyData(ArchivedDate, DbName)
SELECT TOP 1 ArchivedDate, ''' + @CurrentDatabase + '''
FROM ' + @CurrentDatabase + '.dbo.Saveset a
WHERE NOT EXISTS (SELECT * FROM ' + @CurrentDatabase + '.dbo.HoldSaveset b WHERE a.SavesetIdentity = b.SavesetIdentity)'
EXEC(@SQL)
SET @Counter = @Counter + 1
END
SELECT * FROM #MyData
DROP TABLE #MyData
代码解释:此代码首先创建一个名为#MyData 的临时文件Table,其中包含存档日期字段(因为这是您所说的您最感兴趣的内容)。然后在循环中声明一个@CurrentDatabase 变量来保存当前数据库的值。然后它声明一个用于动态 SQL 语句的 @SQL 变量。然后声明用于循环过程的@Counter 变量。
下一行开始循环过程。一旦进入循环,@CurrentDatabase 将通过 selecting 来自 table 变量 @MyDatabases 的下一个顺序数据库来设置。然后使用@CurrentDatabase 变量设置动态SQL 语句。然后执行 Dynamic SQL Statement,将 Dynamic SQL String 的结果插入到 Temp Table.
最后,计数器递增。一旦跳出循环,所有结果都是从 Temp Table 中 select 编辑的。最后,温度 Table 被删除。
希望对您有所帮助。
大家好,我是 SQL 的业余爱好者,但我花了几个小时寻找如何做到这一点,据我所知,没有人描述过它(至少没有说到点子上)我能理解)。
我有一个 SQL 查询,我需要 运行 针对我服务器上的 45 个(非系统)数据库中的每一个:
SELECT TOP 1 IdTransaction, IdDateTime, ArchivedDate, RetentionCategoryIdentity
FROM Saveset
WHERE NOT EXISTS (
SELECT * FROM HoldSaveset
WHERE saveset.SavesetIdentity = HoldSaveset.SavesetIdentity)
由于此查询只有 returns 个结果,我想按数据库名称对这些结果进行分组。如果它能让事情变得更简单,我只是 真正 对 "ArchivedDate" 感兴趣。
您可以使用动态 SQL 创建您的 select 语句。只需将您想要的 table 名称放入 @targetTable 变量中。它将创建一个 table 来存储您的结果。希望这可以帮助!如果您有任何问题,请告诉我!
DECLARE @sql VARCHAR(MAX),
@targetTable VARCHAR(100);
SELECT @sql = 'select top 1 IdTransaction, IdDateTime, ArchivedDate, RetentionCategoryIdentity ' +
'FROM '+ QUOTENAME(name) + '.dbo.Saveset AS A '
+ 'where NOT exists (Select * from ' + QUOTENAME(name) + '.dbo.HoldSaveset AS B ' + 'WHERE A.SavesetIdentity = B.SavesetIdentity) UNION ALL ' + COALESCE(@sql,'')
FROM master..sysdatabases
WHERE NAME NOT IN('master','tempdb','model','msdb')
SET @targetTable = 'database.schema.tablename'
SELECT @sql = 'SELECT * INTO ' + @targetTable + ' FROM (' + SUBSTRING(@sql,0,LEN(@SQL) -8) + ') A';
EXEC (@sql)
您可以查询 sys.databases,在 NAME 字段上使用某种过滤器,将您想要的所有数据库名称插入到 Table 变量中。包含一个可用于循环的顺序字段。该代码看起来像这样。
DECLARE @MyDatabases TABLE (DbName VARCHAR(500), RowNum INT IDENTITY(1,1))
INSERT INTO @MyDatabases (DbName)
SELECT name
FROM sys.databases
WHERE name LIKE '%filter names here%'
一旦您想要的数据库在 Table 变量中,您可以遍历 table,在 Table 中为每个数据库执行一次动态 SQL 语句变量并将结果插入临时 table。循环完成后,您可以 select 临时 table 中的所有值作为最终结果。执行此操作的代码如下所示。
CREATE TABLE #MyData (ArchivedDate VARCHAR(100), DbName VARCHAR(500))
DECLARE @CurrentDatabase VARCHAR(500)
DECLARE @SQL VARCHAR(MAX)
DECLARE @Counter INT = 1
WHILE @Counter <= (SELECT MAX(RowNum) FROM @MyDatabases)
BEGIN
SELECT @CurrentDatabase = DbName
FROM @MyDatabases
WHERE RowNum = @Counter
SET @SQL = 'INSERT INTO #MyData(ArchivedDate, DbName)
SELECT TOP 1 ArchivedDate, ''' + @CurrentDatabase + '''
FROM ' + @CurrentDatabase + '.dbo.Saveset a
WHERE NOT EXISTS (SELECT * FROM ' + @CurrentDatabase + '.dbo.HoldSaveset b WHERE a.SavesetIdentity = b.SavesetIdentity)'
EXEC(@SQL)
SET @Counter = @Counter + 1
END
SELECT * FROM #MyData
DROP TABLE #MyData
代码解释:此代码首先创建一个名为#MyData 的临时文件Table,其中包含存档日期字段(因为这是您所说的您最感兴趣的内容)。然后在循环中声明一个@CurrentDatabase 变量来保存当前数据库的值。然后它声明一个用于动态 SQL 语句的 @SQL 变量。然后声明用于循环过程的@Counter 变量。
下一行开始循环过程。一旦进入循环,@CurrentDatabase 将通过 selecting 来自 table 变量 @MyDatabases 的下一个顺序数据库来设置。然后使用@CurrentDatabase 变量设置动态SQL 语句。然后执行 Dynamic SQL Statement,将 Dynamic SQL String 的结果插入到 Temp Table.
最后,计数器递增。一旦跳出循环,所有结果都是从 Temp Table 中 select 编辑的。最后,温度 Table 被删除。
希望对您有所帮助。