복붙노트

[SQL] 동적 SQL와 열 이름을 통해 루핑

SQL

동적 SQL와 열 이름을 통해 루핑

난 그냥 각 열에 대한 모든 고유 한 값을 보여주고, 각각의 레코드 수를 계산하는 코드의 조각에 대한 아이디어를 내놓았다. 나는 모든 컬럼을 통해 루프 코드를 원한다.

여기에 내가 noobness와 곰 있도록 SQL에 새로운 해요 ... 지금까지이 무엇 :)

하드 코드 :

  select [Sales Manager], count(*)
  from  [BT].[dbo].[test]
  group by [Sales Manager]
  order by 2 desc

동적 SQL에서 시도 :

Declare @sql varchar(max),
@column as varchar(255)

    set @column = '[Sales Manager]'
    set @sql = 'select ' + @column + ',count(*) from [BT].[dbo].[test] group by ' + @column + 'order by 2 desc'

    exec (@sql)

이 잘 작동 모두. 어떻게 모든 컬럼을 통해 루프를 만들 수 있습니까? 열심히 코드에 열 이름을 가지고는 @Column에 대한 각각의 하도를 통해 그것의 방법을 작동하는 경우 난 상관하지 않습니다.

이게 말이 돼?

모두 감사합니다!

해결법

  1. ==============================

    1.당신은 동적 SQL을 사용하고 테이블의 모든 열 이름을 얻을 수 있습니다. 그런 다음 스크립트를 구축 :

    당신은 동적 SQL을 사용하고 테이블의 모든 열 이름을 얻을 수 있습니다. 그런 다음 스크립트를 구축 :

    Declare @sql varchar(max) = ''
    declare @tablename as varchar(255) = 'test'
    
    select @sql = @sql + 'select [' + c.name + '],count(*) as ''' + c.name +  ''' from [' + t.name + '] group by [' + c.name + '] order by 2 desc; ' 
    from sys.columns c
    inner join sys.tables t on c.object_id = t.object_id
    where t.name = @tablename
    
    EXEC (@sql)
    

    변경 (데이터베이스 또는 스키마 이름없이) 테이블의 이름 @tablename.

  2. ==============================

    2.이것은 XY 응답의 약간이지만 열 이름을 하드 코딩 괜찮다면, 나는 그냥 그렇게 제안 및 회피 동적 SQL - 루프를 - 전적으로. 동적 SQL은 일반적으로 마지막 수단으로 간주 보안 문제 (SQL 주입 공격)주의하지 경우에 당신을 열고, 쿼리 및 실행 계획을 캐시 할 수없는 경우 종종 느린 될 수있다.

    이것은 XY 응답의 약간이지만 열 이름을 하드 코딩 괜찮다면, 나는 그냥 그렇게 제안 및 회피 동적 SQL - 루프를 - 전적으로. 동적 SQL은 일반적으로 마지막 수단으로 간주 보안 문제 (SQL 주입 공격)주의하지 경우에 당신을 열고, 쿼리 및 실행 계획을 캐시 할 수없는 경우 종종 느린 될 수있다.

    당신이 열 이름의 톤이있는 경우 당신은 당신을 위해 대체 할 Word에서 코드 또는 편지 병합의 빠른 조각을 쓸 수 있습니다.

    그러나, 지금까지이 SQL 서버입니다 가정, 열 이름을 얻는 방법으로, 다음과 같은 쿼리를 사용할 수 있습니다 :

    SELECT c.name
    FROM sys.columns c
    WHERE c.object_id = OBJECT_ID('dbo.test')
    

    따라서이 쿼리에서 동적 SQL을 구축 할 수 있습니다 :

    SELECT 'select ' 
        + QUOTENAME(c.name) 
        + ',count(*) from [BT].[dbo].[test] group by ' 
        + QUOTENAME(c.name)  
        + 'order by 2 desc'
    FROM sys.columns c
    WHERE c.object_id = OBJECT_ID('dbo.test')
    

    루프 커서를 사용하여.

    또는 하나 개의 배치로 모든 일에 함께 컴파일하고 실행합니다. 여기에서 우리는 ( '') 트릭 용의 XML 경로를 사용 :

    DECLARE @sql VARCHAR(MAX) = (
        SELECT ' select ' --note the extra space at the beginning
            + QUOTENAME(c.name) 
            + ',count(*) from [BT].[dbo].[test] group by ' 
            + QUOTENAME(c.name)  
            + 'order by 2 desc'
        FROM sys.columns c
        WHERE c.object_id = OBJECT_ID('dbo.test')
        FOR XML PATH('')
    )
    
    EXEC(@sql)
    

    내가 사용하고 있습니다 내장 QUOTENAME 기능 이스케이프 필요가 열 이름을 탈출.

  3. ==============================

    3.당신은 테이블의 모든 열에서 별개의 열 값을 알고 싶어? 그냥 다음 코드에서 테이블 이름과 테이블 이름의 직원을 대체 :

    당신은 테이블의 모든 열에서 별개의 열 값을 알고 싶어? 그냥 다음 코드에서 테이블 이름과 테이블 이름의 직원을 대체 :

    declare @SQL nvarchar(max)
    set @SQL = ''
    ;with cols as (
    select Table_Schema, Table_Name, Column_Name, Row_Number() over(partition by Table_Schema, Table_Name
    order by ORDINAL_POSITION) as RowNum
    from INFORMATION_SCHEMA.COLUMNS
    )
    
    select @SQL = @SQL + case when RowNum = 1 then '' else ' union all ' end
    + ' select ''' + Column_Name + ''' as Column_Name, count(distinct ' + quotename (Column_Name) + ' ) As DistinctCountValue, 
    count( '+ quotename (Column_Name) + ') as CountValue FROM ' + quotename (Table_Schema) + '.' + quotename (Table_Name)
    from cols
    where Table_Name = 'Employee' --print @SQL
    
    execute (@SQL)
    
  4. from https://stackoverflow.com/questions/20463365/looping-through-column-names-with-dynamic-sql by cc-by-sa and MIT license