2017-04-16 3 views
1

これが重複している場合はお詫び申し上げます。私は検索中にかなり時間を費やしていて、私の質問に正確な答えを見つけることができません。GROUP BY列を無効にする

私は引数に応じて、いずれかの年、月または年だけでグループ化された行を返します(MSSQLで)SQL関数内蔵されている

CREATE FUNCTION get_report (@grouping VARCHAR(30)) 
RETURNS TABLE 
AS 
RETURN 
(
SELECT 
    YEAR(t.my_date) as my_year, 
    CASE when @grouping = 'monthly' THEN MONTH(t.my_date) ELSE null END as my_month, 
    count(t.row_id) as num_rows, 
    round(avg(my_val),4) as avg_my_val 
FROM 
    my_schema.my_info t 
GROUP BY 
    year(t.my_date), 
    CASE when @grouping = 'monthly' THEN month(t.my_date) ELSE null END 
) 

これは、月によって私のグループ化を与えることに成功したのか、レポートをどのようにしたいかに応じて、

しかし、理想的には、@grouping = 'none'にグループ化を完全に排除してアイテムのリストを表示するというオプションが必要です。私はこのクエリがあまりにも多くのことを強制しようとしている可能性がありますが、そうでないかもしれません。私はGROUP BY 0のようなものを試しましたが、それは私が望むことをしません。そして、GROUP BY rand()はあまりにも面倒です。

提案がありますか?

+0

MSSQL、申し訳ありません私は – Stephen

+0

私の答えをチェックしにこれを追加します、ありがとうございました。 –

+0

が完了してください質問 – Stephen

答えて

2

これを試してみてください:

use tsql2012 

create table dbo.test18 
(
    year int not null, 
    month int not null, 
    value int 
); 

insert into dbo.test18 
values (2017, 4, 250), (2017, 4, 150), (2017, 4, 660), (2017, 4, 1110), (2017, 3, 1250), (2017, 2, 2540), (2017, 3, 2500) 

declare @a varchar(30) = 'none' 

select * from (
    select grouping_id(year, month, value) as gr_id, year, month, sum(value) as sm 
    from dbo.test18 
    group by grouping sets((year), (month), (year, month), (year, month, value)) 
) t 
where 
    gr_id < case when @a = 'none' then 1 else 999 end 
    and gr_id > case when @a = 'none' then -1 else 0 end 
+0

この回答は、私が欲しいものを私に与えるように見えるので、私はそれを受け入れました。私のプロジェクト計画は変更されましたが、将来これを使用すると、正しいgrouping_idを探すためのwhere条件を追加するだけでよいように見えます。 – Stephen

1

グループ化をパラメータ化することはできません。同様に、クエリ構造をパラメータ化することはできません(キャッシュできない実行計画が異なるため)。

  1. 使用ダイナミックSQL(すなわち、T-SQL内のSQL文字列を構築し、これはSPROCを、ないUDFでなければならないであろう):

    は、3つのソリューションがあります。

  2. SQLを動的に生成するORMを使用してください(例:Linq-to-EntitiesまたはNHibernateなど)
  3. グループ化されていないバージョンの2番目のUDFを作成します。