2013-12-09 15 views
6

各列の個別の値をすべて表示し、それぞれのレコードの数を数えるコードのアイディアを思いついただけです。私はコードがすべての列をループするようにします。動的SQLで動的SQLで列名をループする

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

試み:

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) 
ここ

はそうnoobness容赦:)

ハードコードを、私は今のところ...私はSQLに新たなんだてきたものです

これらはどちらも問題なく動作します。どのようにすべての列をループすることができますか?列名を厳密にコード化しなければならないかどうかは気にせず、各列の@columnに下線を引いています。

これは意味がありますか?

ありがとうございます!

答えて

5

動的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:次に、スクリプトを構築します。

+1

私はこのコードを試しました...それは走ったようでしたが、私は何かを追加するつもりですか?私はそこにループがないのですか?乾杯、 – Lucas

+1

あなたはループを必要としません、すべての列のすべてのクエリは '@ sql'変数にあります。 – Szymon

+0

Hey Szymon。さて、私はそれを得ると思う...ハハ。私は 'コマンドが正常に完了しました'が表示されますが、結果は表示されません...自分のコードのどの部分を自分の値に変更する必要がありますか? – Lucas

8

これはちょっとしたXY答えですが、列名をハードコーディングしても構わないのであれば、それだけで、動的SQLやループを避けることをお勧めします。動的SQLは一般的に最後の手段とみなされます。注意しないとセキュリティ問題(SQLインジェクション攻撃)が発生し、クエリや実行計画をキャッシュできない場合には時間がかかることがあります。

大量の列名を使用している場合は、置換えを行うために、Wordでコードまたは差し込み印刷の簡単な部分を書くことができます。

限りカラム名を取得する方法として、しかし

、これがSQL Serverであると仮定すると、あなたは次のクエリを使用することができます。

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') 

カーソルを使用してループします。

または、すべてをまとめて1つのバッチにまとめて実行します。私はエスケープする必要がカラム名をエスケープするthe built-in QUOTENAME functionを使用しています

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) 

注:ここでは、FOR XML PATH('')トリックを使用しています。

関連する問題