2017-08-24 33 views
3

我有查询,列出在我的数据库中的所有表各自的指标:SQL递归指数调查结果查询

SELECT 
    TableName = t.name, 
    IndexName = ind.name, 
    IndexId = ind.index_id, 
    ColumnId = ic.index_column_id, 
    ColumnName = col.name, 
    ind.*, 
    ic.*, 
    col.* 
FROM 
    sys.indexes ind 
INNER JOIN 
    sys.index_columns ic ON ind.object_id = ic.object_id and ind.index_id = ic.index_id 
INNER JOIN 
    sys.columns col ON ic.object_id = col.object_id and ic.column_id = col.column_id 
INNER JOIN 
    sys.tables t ON ind.object_id = t.object_id 
WHERE 
    ind.is_primary_key = 0 
    AND ind.is_unique = 0 
    AND ind.is_unique_constraint = 0 
    AND t.is_ms_shipped = 0 

我得到的输出是这样的:

enter image description here

TableName -> contain Table names in DB ColumName -> contain Index column name for each table in DB

我的目标是绘制备案和最后一个(最大)的ColumnName值的每"TableName" + "ColumnName" TOT数。

基本上就在标签格式输出,我想获得: enter image description here

你有任何想法如何递归地产生这样的结果在一个单一的查询? 谢谢!

+1

*“为每个绘图”TableName“+”ColumnName“记录的TOT编号和最后一个(最大)ColumnName值。”*:我不知道这意味着什么。你可以在你的问题中包含表格,因为你希望输出是? – trincot

+0

刚刚添加。基本上从主查询,我需要每各表名以及每个的ColumnName迭代并获得记录和最后一个值的TOT数。 – user3925023

+0

@ user3925023 - 每个表都有主键? – Poonam

回答

1

好,这可能是速度不够快,在你的安装运行,是我最好的尝试。有涉及列和max()骨料的类型,这决定了max_value应该是一个varchar问题。

只要确保你use your_database_name创建和执行这个程序,这对于应用程序调用类似于单查询之前。

create proc stp_generateColInfo as 

declare 
@tablename varchar(1000), 
@columnname varchar(1000) 

set nocount on 

create table #TMP_DDL (
    TableName varchar(1000), 
    ColumnName varchar(1000), 
    TOTAL int, 
    MAX_VALUE varchar(8000) 
); 

INSERT INTO #TMP_DDL 
SELECT 
    TableName = t.name, 
    ColumnName = col.name, 
    0 as TOTAL, 
    '' as MAX_VALUE 
FROM 
    sys.indexes ind 
INNER JOIN 
    sys.index_columns ic ON ind.object_id = ic.object_id and ind.index_id = ic.index_id 
INNER JOIN 
    sys.columns col ON ic.object_id = col.object_id and ic.column_id = col.column_id 
INNER JOIN 
    sys.tables t ON ind.object_id = t.object_id 
WHERE 
    ind.is_primary_key = 0 
    AND ind.is_unique = 0 
    AND ind.is_unique_constraint = 0 
    AND t.is_ms_shipped = 0 


declare cs cursor local static forward_only for 
    select TableName, ColumnName from #TMP_DDL 

open cs 
fetch next from cs into @tablename, @columnname 
while @@FETCH_STATUS=0 
begin 
    exec(' 
    declare @total int, @max_value varchar(8000) 
    select @total=count(*), @max_value=max(IsNull(' + @columnname + ',0)) from ' + @tablename + ' 
    update #TMP_DDL set [email protected], [email protected]_value where TableName=''' + @tablename + ''' and ColumnName=''' + @columnname + '''' 
    ) 
    fetch next from cs into @tablename, @columnname 
end 

close cs 
deallocate cs 

set nocount off 

--Add joins here to select additional columns :) 
select * from #TMP_DDL 

go 
+0

有没有办法避免创建表?我没有权利这样做.Thx – user3925023

+1

请参阅:https://jasonstrate.com/2013/05/21/security-questions-what-permissions-are-需要创建临时表/我认为每个用户都有权创建临时表! – Niloct

1

你有任何想法如何递归地产生这样的结果在 单个查询?

这是不可能的。

您需要单独调用动态SQL语句

SET @sql = 'SELECT @MaxID = MAX('[email protected]+') FROM '[email protected] 

您的结果集的每一行和functions cannot contain dynamic SQL这是不可能把它写在SQL Server的一个select语句。您不能单独调用动态SQL或a stored procedure为每一个行中的一个查询。

在Oracle中有像BULK COLLECT and FORALL这样的命令允许将结果集与逐行处理结合起来,但我不知道SQL Server中存在类似的东西。