Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
SQL Server 2008-如何查找前10个表并对其排序_Sql_Sql Server - Fatal编程技术网

SQL Server 2008-如何查找前10个表并对其排序

SQL Server 2008-如何查找前10个表并对其排序,sql,sql-server,Sql,Sql Server,嗨,我有以下脚本: DECLARE @sql VARCHAR(2000); DECLARE @tableName SYSNAME; DECLARE @columnName SYSNAME; DECLARE @count INT; DECLARE @NotCursor TABLE(ID INT IDENTITY(1, 1), TableName SYSNAME, ColumnName SYSNAME) DECLARE

嗨,我有以下脚本:

DECLARE @sql VARCHAR(2000);
DECLARE @tableName SYSNAME;
DECLARE @columnName SYSNAME;
DECLARE @count INT;
DECLARE @NotCursor TABLE(ID INT IDENTITY(1, 1),
                    TableName SYSNAME,
                    ColumnName SYSNAME)
DECLARE @StartLoop INT
DECLARE @EndLoop INT
DECLARE @SQLFinalQuery VARCHAR(MAX)

INSERT INTO @NotCursor
SELECT TABLE_NAME,
      COLUMN_NAME
FROM INFORMATION_SCHEMA.COLUMNS
WHERE
(DATA_TYPE = 'date'
OR DATA_TYPE = 'datetime')
AND table_name NOT LIKE '%[_]%'
ORDER BY TABLE_NAME

SELECT @StartLoop = MIN(ID),
      @EndLoop = MAX(ID)
FROM @NotCursor

SET @SQLFinalQuery = ';WITH cte_Resultset AS'+CHAR(13)+CHAR(10)
+'('

WHILE @StartLoop <= @EndLoop
    BEGIN
       SELECT @tableName = TableName,
            @columnName = ColumnName
       FROM @NotCursor
       WHERE  ID = @StartLoop

       SET @sql = 'SELECT ''' + @tableName + ''' as [TableName], ' + '''' + @columnName + ''' AS [ColumnName], ' + 'DATEPART(yy, ' + QUOTENAME(@columnName) + ') AS [Year], COUNT(1) AS [NumberofRows]'+CHAR(13)+CHAR(10)
       +'FROM ' + QUOTENAME(@tableName) +CHAR(13)+CHAR(10) 
       +'GROUP BY DATEPART(yy, ' + QUOTENAME(@columnName) + ')';
       SET @SQLFinalQuery = @SQLFinalQuery+CHAR(13)+CHAR(10)+@sql;

       SET @SQLFinalQuery =   CASE 
                             WHEN @StartLoop = @EndLoop THEN @SQLFinalQuery+CHAR(13)+CHAR(10)+')'
                             ELSE @SQLFinalQuery+CHAR(13)+CHAR(10)+'UNION ALL' 
                          END

       SET @StartLoop = @StartLoop + 1

    END
SET @SQLFinalQuery = @SQLFinalQuery +'SELECT TOP 10 SUM(NumberofRows) AS NumberOfRows,TableName,ColumnName,Year'+CHAR(13)+CHAR(10)
+'FROM cte_Resultset'+CHAR(13)+CHAR(10)
+'WHERE Year IS NOT NULL'+CHAR(13)+CHAR(10) 
+'GROUP BY TableName, ColumnName, Year'+CHAR(13)+CHAR(10)
+'ORDER BY SUM(NumberofRows) DESC'+CHAR(13)+CHAR(10)

EXEC (@SQLFinalQuery)

只需在表变量中收集结果,然后从该表中选择:

DECLARE @sql varchar(2000);
DECLARE @tableName sysname; 
DECLARE @columnName sysname;
DECLARE @count int;
DECLARE theCursor CURSOR FOR

SELECT TABLE_NAME, COLUMN_NAME
FROM INFORMATION_SCHEMA.COLUMNS
WHERE
  (DATA_TYPE = 'date' or DATA_TYPE = 'datetime')
  and table_name not like '%[_]%'
ORDER BY TABLE_NAME 

OPEN theCursor;
FETCH NEXT FROM theCursor INTO @tableName, @columnName;

DECLARE @tables TABLE (TableName nvarchar(128), ColumnName nvarchar(128), 
                Year int, NumberofRows int)
WHILE @@FETCH_STATUS = 0
BEGIN
  SET @sql = 'SELECT ''' + @tableName + ''' as [TabelName], ' + 
             '''' + @columnName + ''' AS [ColumnName], ' +
             'DATEPART(yy, ' + QUOTENAME(@columnName) + 
             ') AS [Year], COUNT(1) AS [NumberofRows] FROM ' + QUOTENAME(@tableName) + 
             ' GROUP BY DATEPART(yy, ' + QUOTENAME(@columnName) + ')';
  PRINT @sql;
  INSERT INTO @tables
  EXEC (@sql);

  FETCH NEXT FROM theCursor INTO @tableName, @columnName;
END

SELECT TOP 10 SUM(NumberofRows) NumberOfRows, tableName, Year FROM @tables GROUP BY TableName, Year ORDER BY SUM(NumberofRows) DESC
CLOSE theCursor
DEALLOCATE theCursor;

基于OP希望获得所有表的计数的更新注释,而不仅仅是最大的10个计数,这可以在没有循环的情况下完成

declare @SQL nvarchar(max)

select @SQL = 
STUFF((
select top 20 'SELECT ''' + TABLE_NAME + ''' as [TableName], ' + 
             '''' + COLUMN_NAME + ''' AS [ColumnName], ' +
             'DATEPART(yy, ' + QUOTENAME(COLUMN_NAME) + 
             ') AS [Year], COUNT(1) AS [NumberofRows] FROM ' + QUOTENAME(TABLE_NAME) + 
             ' GROUP BY DATEPART(yy, ' + QUOTENAME(COLUMN_NAME) + ') union all '
from INFORMATION_SCHEMA.COLUMNS
WHERE
  (DATA_TYPE = 'date' or DATA_TYPE = 'datetime')
  and table_name not like '%[_]%'
ORDER BY TABLE_NAME 
for xml path('')),1 , 0 , '')

select @SQL = stuff(@SQL, len(@SQL) - 9, 10, '') + ' order by NumberOfRows desc'

exec sp_executesql @SQL

@用户3712641,这个答案与来自

当我能够回答时,原来的线程已作为副本关闭。然而,由于我已经花了一些时间来优化这个查询,我将继续添加到这篇文章中

我所做的是删除循环插入并消除游标。在本地机器上的测试表明性能有所提高。请尝试让我知道它是否适合你

DECLARE @sql VARCHAR(2000);
DECLARE @tableName SYSNAME;
DECLARE @columnName SYSNAME;
DECLARE @count INT;
DECLARE @NotCursor TABLE(ID INT IDENTITY(1, 1),
                    TableName SYSNAME,
                    ColumnName SYSNAME)
DECLARE @StartLoop INT
DECLARE @EndLoop INT
DECLARE @SQLFinalQuery VARCHAR(MAX)

INSERT INTO @NotCursor
SELECT TABLE_NAME,
      COLUMN_NAME
FROM INFORMATION_SCHEMA.COLUMNS
WHERE
(DATA_TYPE = 'date'
OR DATA_TYPE = 'datetime')
AND table_name NOT LIKE '%[_]%'
ORDER BY TABLE_NAME

SELECT @StartLoop = MIN(ID),
      @EndLoop = MAX(ID)
FROM @NotCursor

SET @SQLFinalQuery = ';WITH cte_Resultset AS'+CHAR(13)+CHAR(10)
+'('

WHILE @StartLoop <= @EndLoop
    BEGIN
       SELECT @tableName = TableName,
            @columnName = ColumnName
       FROM @NotCursor
       WHERE  ID = @StartLoop

       SET @sql = 'SELECT ''' + @tableName + ''' as [TableName], ' + '''' + @columnName + ''' AS [ColumnName], ' + 'DATEPART(yy, ' + QUOTENAME(@columnName) + ') AS [Year], COUNT(1) AS [NumberofRows]'+CHAR(13)+CHAR(10)
       +'FROM ' + QUOTENAME(@tableName) +CHAR(13)+CHAR(10) 
       +'GROUP BY DATEPART(yy, ' + QUOTENAME(@columnName) + ')';
       SET @SQLFinalQuery = @SQLFinalQuery+CHAR(13)+CHAR(10)+@sql;

       SET @SQLFinalQuery =   CASE 
                             WHEN @StartLoop = @EndLoop THEN @SQLFinalQuery+CHAR(13)+CHAR(10)+')'
                             ELSE @SQLFinalQuery+CHAR(13)+CHAR(10)+'UNION ALL' 
                          END

       SET @StartLoop = @StartLoop + 1

    END
SET @SQLFinalQuery = @SQLFinalQuery +'SELECT TOP 10 SUM(NumberofRows) AS NumberOfRows,TableName,Year'+CHAR(13)+CHAR(10)
+'FROM cte_Resultset'+CHAR(13)+CHAR(10)
+'GROUP BY TableName, Year'+CHAR(13)+CHAR(10)
+'ORDER BY SUM(NumberofRows) DESC'+CHAR(13)+CHAR(10)

EXEC (@SQLFinalQuery)

出于好奇,它是否必须通过代码,或者您不能使用SSMS中内置的
磁盘使用情况表
报告?我更希望通过代码来实现,因为当我运行脚本时,我希望能够看到SQL Server结果窗口中显示的前10个表。这样它就可以被多人使用。所以我知道列名在最终结果中并不重要。这是一个多么奇怪的要求。不太确定这是在做什么,但似乎您正在尝试从任何表中获取前10个datetime列?你为什么要用光标来做这个?不,不是,我只是把它放在那里,看看哪些行与哪个列相关,但不,这并不重要。它看起来工作得很好,呈现的方式也很干净。太好了,谢谢!我一点也不喜欢这里的游标方法,但是如果你喜欢,你应该在里面添加一个计数器,这样一旦table变量有10行,你就可以退出循环。否则,您只需继续运行最终查询将忽略的sql。我将提出一种更基于集合的方法,在没有游标的情况下也可以做同样的事情。声明@RowCountMax int=1。然后使用第二个条件修改While(并且@RowCountMax<10)。最后,在执行动态sql之后立即添加此项(set@RowCountMax=@@ROWCOUNT)。这至少会迫使循环在得到10行之后退出。好的,Sean,但是我们不知道前10个表,除非我们遍历所有表并计算匹配的行。您的建议使代码只返回按名称排序的前10个表。现在,您从前10个表开始,没有必要得到更多。然后将循环中的行数限制为10,因为这就是您要选择的所有行数。您好,感谢您的回复!它确实似乎工作得更好,并且提供了与以前相同的信息。看起来不错,谢谢你的帮助。很高兴它对你有用。嗨,我更新了我的问题,我忘了我也想在输出中有列名,但似乎无法让它工作,你能帮我一下吗?@user3712641,我已按要求将列添加到结果集中。效果很好,再次感谢你。我想当我试图在我的代码上修改它时,它要困难得多,但是使用您提供的代码要容易得多。
DECLARE @sql VARCHAR(2000);
DECLARE @tableName SYSNAME;
DECLARE @columnName SYSNAME;
DECLARE @count INT;
DECLARE @NotCursor TABLE(ID INT IDENTITY(1, 1),
                    TableName SYSNAME,
                    ColumnName SYSNAME)
DECLARE @StartLoop INT
DECLARE @EndLoop INT
DECLARE @SQLFinalQuery VARCHAR(MAX)

INSERT INTO @NotCursor
SELECT TABLE_NAME,
      COLUMN_NAME
FROM INFORMATION_SCHEMA.COLUMNS
WHERE
(DATA_TYPE = 'date'
OR DATA_TYPE = 'datetime')
AND table_name NOT LIKE '%[_]%'
ORDER BY TABLE_NAME

SELECT @StartLoop = MIN(ID),
      @EndLoop = MAX(ID)
FROM @NotCursor

SET @SQLFinalQuery = ';WITH cte_Resultset AS'+CHAR(13)+CHAR(10)
+'('

WHILE @StartLoop <= @EndLoop
    BEGIN
       SELECT @tableName = TableName,
            @columnName = ColumnName
       FROM @NotCursor
       WHERE  ID = @StartLoop

       SET @sql = 'SELECT ''' + @tableName + ''' as [TableName], ' + '''' + @columnName + ''' AS [ColumnName], ' + 'DATEPART(yy, ' + QUOTENAME(@columnName) + ') AS [Year], COUNT(1) AS [NumberofRows]'+CHAR(13)+CHAR(10)
       +'FROM ' + QUOTENAME(@tableName) +CHAR(13)+CHAR(10) 
       +'GROUP BY DATEPART(yy, ' + QUOTENAME(@columnName) + ')';
       SET @SQLFinalQuery = @SQLFinalQuery+CHAR(13)+CHAR(10)+@sql;

       SET @SQLFinalQuery =   CASE 
                             WHEN @StartLoop = @EndLoop THEN @SQLFinalQuery+CHAR(13)+CHAR(10)+')'
                             ELSE @SQLFinalQuery+CHAR(13)+CHAR(10)+'UNION ALL' 
                          END

       SET @StartLoop = @StartLoop + 1

    END
SET @SQLFinalQuery = @SQLFinalQuery +'SELECT TOP 10 SUM(NumberofRows) AS NumberOfRows,TableName,Year'+CHAR(13)+CHAR(10)
+'FROM cte_Resultset'+CHAR(13)+CHAR(10)
+'GROUP BY TableName, Year'+CHAR(13)+CHAR(10)
+'ORDER BY SUM(NumberofRows) DESC'+CHAR(13)+CHAR(10)

EXEC (@SQLFinalQuery)
SET @SQLFinalQuery = @SQLFinalQuery +'SELECT TOP 10 SUM(NumberofRows) AS NumberOfRows,TableName,ColumnName,Year'+CHAR(13)+CHAR(10)
+'FROM cte_Resultset'+CHAR(13)+CHAR(10)
+'GROUP BY TableName, ColumnName, Year'+CHAR(13)+CHAR(10)
+'ORDER BY SUM(NumberofRows) DESC'+CHAR(13)+CHAR(10)

EXEC (@SQLFinalQuery)