如何将DRY原理应用于枢纽月份的SQL语句 [英] How to apply the DRY principle to SQL Statements that Pivot Months

查看:93
本文介绍了如何将DRY原理应用于枢纽月份的SQL语句的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想知道其他人如何处理这种情况……以及如何将不要重复自己的"(DRY)原则应用于这种情况.

I'm wondering how others handle this situation... and how to apply the Don't Repeat Yourself (DRY) principle to this situation.

我发现自己经常在T-SQL中使用PIVOTing或编写CASE语句以将Months表示为列.我通常有一些字段,其中将包括(1)日期字段和(2)值字段.当我通过ASPX页面或Reporting Services将其呈现给用户时,我需要在最右边的14列中具有此模式:

I find myself constantly PIVOTing or writing CASE statements in T-SQL to present Months as columns. I generally have some fields that will include (1) a date field and (2) a value field. When I present this back to a user through an ASPX page or Reporting Services I need to have the last right-most 14 columns to have this pattern:

[年份],[Jan],[Feb],[Mar],[Apr],[May],[Jun],[Jul],[Aug],[Sep],[Oct],[Nov] ,[Dec],[Total]

[Year],[Jan],[Feb],[Mar],[Apr],[May],[Jun],[Jul],[Aug],[Sep],[Oct],[Nov],[Dec],[Total]

年份是整数年份 其他所有字段都是该月的总和(不包括[Total],这是该年的总价值).

Where year is the year as an int and every other field is the value field summed for that month (except for [Total] which is the total value field for the year).

我想找到一种可重复使用的方式来处理此问题.打开所有建议(T-SQL/ANSI SQL)

I'd like to find one re-usable way to handle this. Open to all suggestions (T-SQL / ANSI SQL)

推荐答案

这并非您所要的,但我已经做了很多重复的UNPIVOT,通常,我会进行代码生成通过某种标准化的命名方式,并大量使用CTE:

This isn't exactly what you're looking for, but I've done a lot of repetitive UNPIVOT, and typically, I would code-gen this, with some kind of standardized naming and use CTEs heavily:

WITH P AS (
    SELECT Some Data
            ,[234] -- These are stats
            ,[235]
    FROM Whatever
     )
,FINAL_UNPIVOTED AS (
    SELECT Some Data
            ,[STAT]
    FROM P
    UNPIVOT (
        STAT FOR BASE IN ([234], [235]) 
    ) AS unpvt
    WHERE STAT <> 0
)
SELECT Some Data
              ,CONVERT(int, FINAL_UNPIVOTED.[BASE]) AS [BASE]
              ,FINAL_UNPIVOTED.[STAT]
FROM FINAL_UNPIVOTED

您可以通过检查表或视图并使用如下代码来进行代码生成:

You can codegen by inspecting a table or view and using something like this:

DECLARE @sql_unpivot AS varchar(MAX)
SELECT @sql_unpivot = COALESCE(@sql_unpivot + ',', '') + COLUMN_NAME
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME = 'whatever'

然后对代码进行模板化:

And templatizing the code:

SET @template = '
    WITH P AS (
        SELECT Some Data
                ,{@sql_unpivot}
                  FROM Whatever
         )
    ,FINAL_UNPIVOTED AS (
        SELECT Some Data
                ,[STAT]
        FROM P
        UNPIVOT (
            STAT FOR BASE IN ({@sql_unpivot}) 
        ) AS unpvt
        WHERE STAT <> 0
    )
    SELECT Some Data
                  ,CONVERT(int, FINAL_UNPIVOTED.[BASE]) AS [BASE]
                  ,FINAL_UNPIVOTED.[STAT]
    FROM FINAL_UNPIVOTED
'
SET @sql = REPLACE(@template, '{@sql_unpivot}', @sql_unpivot)

当然,可以动态运行此代码,也可以创建和SP,并且可以换出临时创建的视图或表,而只是为某些内联控件获取元数据.

Of course, it's possible to run this code dynamically or create and SP and you can swap out a view or table you created temporarily just to pick up metadata for something inline.

请参阅有关表值函数和OUTER APPLY技术的注释.

See comments regarding table-valued functions and OUTER APPLY technique.

这篇关于如何将DRY原理应用于枢纽月份的SQL语句的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆