窗口上的TSQL计数

时间:2014-12-12 22:38:13

标签: tsql window-functions

找不到我需要的问题/答案,但找不到例子。我想使用窗口函数。

我有以下模式来保存存储过程以及这些过程中使用的表和列:

CREATE TABLE [dbo].[ProcedureDependencies](
[DatabaseName] [varchar](256) NOT NULL,
[ProcedureId] [int] NOT NULL,
[ProcedureSchemaName] [varchar](256) NOT NULL,
[ProcedureName] [varchar](256) NOT NULL,
[TableSchemaName] [varchar](256) NOT NULL,
[TableName] [varchar](256) NOT NULL,
[FieldName] [varchar](256) NOT NULL)

我想计算一个表名显示 不同 程序的次数。

我一直尝试以下各种变体:

select 
    DatabaseName,
    TableName, 
    count(tablename) over (partition by DatabaseName,ProcedureName) cnt
from ProcedureDependencies
order by cnt desc

然而,我的结果不好。例如,在我想要的脚本中......

databasename    tablename    cnt
db1             tbl1         3
db1             tbl2         1
db1             tbl3         1

但我得到......

databasename    tablename    cnt
db1             tbl1         3
db1             tbl2         3
db1             tbl3         3
db1             tbl1         1

剧本:

drop table #tmprmd;
create table #tmprmd (
    DatabaseName varchar(max),
    TableName varchar(max), 
    ProcedureName varchar(max), 
    FieldName varchar(max));
Insert Into #tmprmd
Values  ('db1',     'tbl1',     'proc1',    'field1'),
        ('db1',     'tbl1',     'proc1',    'field2'),
        ('db1',     'tbl2',     'proc1',    'field1'),
        ('db1',     'tbl1',     'proc2',    'field1'),
        ('db1',     'tbl3',     'proc1',    'field1'),
        ('db1',     'tbl1',     'proc3',    'field1');
with 
dist as (
    select 
        --distinct
        databasename,
        procedurename,
        tablename
    from #tmprmd--ProcedureDependencies
)
select 
distinct
    DatabaseName,
    TableName, 
    count(tablename) over (partition by DatabaseName,procedurename) cnt
from dist
order by cnt desc

2 个答案:

答案 0 :(得分:2)

我认为你正在努力实现这一目标

drop table #tmprmd;
create table #tmprmd (
    DatabaseName varchar(max),
    TableName varchar(max), 
    ProcedureName varchar(max), 
    FieldName varchar(max));
Insert Into #tmprmd
Values  ('db1',     'tbl1',     'proc1',    'field1'),
        ('db1',     'tbl1',     'proc1',    'field2'),
        ('db1',     'tbl2',     'proc1',    'field1'),
        ('db1',     'tbl3',     'proc1',    'field1'),
        ('db1',     'tbl1',     'proc2',    'field1'),       
        ('db1',     'tbl1',     'proc3',    'field1');
select dist.DatabaseName, dist.TableName, count(distinct(procedurename)) 
from #tmprmd as dist  
group by dist.DatabaseName, dist.TableNameName

答案 1 :(得分:0)

        IF OBJECT_ID('Tempdb..#tmprmd') IS NOT NULL 
            DROP TABLE #tmprmd
        CREATE TABLE #tmprmd
            (
              DatabaseName VARCHAR(MAX) ,
              TableName VARCHAR(MAX) ,
              ProcedureName VARCHAR(MAX) ,
              FieldName VARCHAR(MAX)
            );
        INSERT  INTO #tmprmd
        VALUES  ( 'db1', 'tbl1', 'proc1', 'field1' ),
                ( 'db1', 'tbl1', 'proc1', 'field2' ),
                ( 'db1', 'tbl2', 'proc1', 'field1' ),
                ( 'db1', 'tbl1', 'proc2', 'field1' ),
                ( 'db1', 'tbl3', 'proc1', 'field1' ),
                ( 'db1', 'tbl1', 'proc3', 'field1' );
----------------------------------------------------------
    -- variant 1
        WITH    cte
                  AS ( SELECT DISTINCT
                                T.DatabaseName ,
                                T.TableName ,
                                COUNT(*) OVER ( PARTITION BY T.DatabaseName, T.ProcedureName, T.TableName ) cnt
                       FROM     #tmprmd AS T
                     )
            SELECT  DISTINCT
                    DatabaseName ,
                    TableName ,
                    SUM(cte.cnt) OVER ( PARTITION BY DatabaseName, TableName ) cnt
            FROM    cte
----------------------------------------------------------
    --variant 2
    SELECT DISTINCT dist.DatabaseName,
                    dist.TableName,
                    MAX(cnt) OVER (PARTITION BY dist.DatabaseName, dist.TableName) cnt
    FROM (  SELECT DISTINCT T.DatabaseName,
                            T.TableName,
                            DENSE_RANK() OVER (PARTITION BY T.TableName order by T.ProcedureName ) cnt
            FROM #tmprmd AS T
         ) dist
----------------------------------------------------------
    --variant 3
    SELECT DISTINCT dist.DatabaseName,
                    dist.TableName,
                    COUNT(cnt) OVER (PARTITION BY dist.DatabaseName, dist.TableName) cnt
    FROM (  SELECT DISTINCT T.DatabaseName,
                            T.TableName,
                            DENSE_RANK() OVER (PARTITION BY T.TableName order by T.ProcedureName ) cnt
            FROM #tmprmd AS T
         ) dist
----------------------------------------------------------
    -- Variant 4, without using window function
    SELECT T.DatabaseName,
           T.TableName,
           COUNT(DISTINCT T.ProcedureName ) cnt
    FROM #tmprmd AS T
    GROUP BY T.DatabaseName,T.TableName