2014-12-12 6 views
0

Не удалось найти вопрос/ответ, который был совершенно то, что мне нужно, и не мог найти примеры. Я хотел бы использовать функцию окна.TSQL Count Over a Window

У меня есть следующая схема, которая содержит сохраненные проки и таблицу и столбцы, используемые в этих прокамах:

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 
+0

Shoudnt это 4,1,1 желаемых результатов? – Mihai

+1

@Mihai нет, должно быть 3,1,1 – Vasily

ответ

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 
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 
+0

Вариант 4 - это ответ, который я опубликовал за 13 часов до вашего редактирования. Вы заглянули? – Paparazzi

+0

@Blam, да, с предыдущим повышением, если у вас есть objecion, я могу удалить его из моего сообщения. – Vasily