整合数据的最佳方式

mas*_*nix 5 sql-server-2008

我有三个 select 语句,它们的大部分列都是相同的,除了少数。所以这是一个例子

select
*orgid='0'
,'P' as OrgType*
, Lang
,*cast(Null as varchar) as BoardName
,cast(Null as varchar) as SchoolName*

,SUM(CASE WHEN IncludeColumn = 1 AND SecondInclude IN(5) THEN 1 ELSE 0 END) as Column1
,SUM(CASE WHEN IncludeColumn = 1 AND SecondInclude IN(6) THEN 1 ELSE 0 END) as Column2
,SUM(CASE WHEN IncludeColumn = 1 AND SecondInclude IN(4) THEN 1 ELSE 0 END) as Column3

FROM *TABLEA*
WHERE *[Include_All] = 1* 
Group By *[Lang]*



select
orgid=boardname
,'B' as OrgType
, Lang
, BoardName
,cast(Null as varchar) as SchoolName


,SUM(CASE WHEN IncludeColumn = 1 AND SecondInclude IN(5) THEN 1 ELSE 0 END) as Column1
,SUM(CASE WHEN IncludeColumn = 1 AND SecondInclude IN(6) THEN 1 ELSE 0 END) as Column2
,SUM(CASE WHEN IncludeColumn = 1 AND SecondInclude IN(4) THEN 1 ELSE 0 END) as Column3
FROM TABLEB
WHERE [Include_Board] = 1 
Group By [Lang], BoardName


select
orgid=SchoolName
,'S' as OrgType
, Lang
, BoardName
,SchoolName

,SUM(CASE WHEN IncludeColumn = 1 AND SecondInclude IN(5) THEN 1 ELSE 0 END) as Column1
,SUM(CASE WHEN IncludeColumn = 1 AND SecondInclude IN(6) THEN 1 ELSE 0 END) as Column2
,SUM(CASE WHEN IncludeColumn = 1 AND SecondInclude IN(4) THEN 1 ELSE 0 END) as Column3

FROM TABLEC
WHERE [Include_School] = 1 
Group By [Lang], BoardName
Run Code Online (Sandbox Code Playgroud)

如您所见,每个“分组”中的计算列都是相同的。问题是我在所有三个 select 语句中都有大约 70 个计算字段(相同)。这使得阅读脚本变得可怕,因为我必须无休止地滚动。

主要的变化是 select 语句中的前几列,然后是它在最后的分组方式。

现在我当前的解决方案是设置字符串并执行它们。IE,我会的

header1 = "SELECT FROM all..." 
header2 = "SELECT FROM board.."
header3 = "SELECT FROM school.."
footer1 = "GROUP BY lang"
footer2 = "GROUP BY lang, board"
footer3 = "GROUP BY lang, school" 
Common = CalculatedFields

EXECUTE (header1 + common + footer1)
EXECUTE (header2 + common + footer2)
Run Code Online (Sandbox Code Playgroud)

但这只会使我的脚本全部变红,因为它是一个大字符串。不仅因为我有很多文本,所以我必须将它分解成不同的字符串。

关于如何在保持可读性和清晰度的同时最好地做到这一点的任何想法?

Pie*_*ens 0

使用CROSS APPLY(或者可能是 OUTER APPLY)来替换聚合中的 case 语句,如下所示:

with f as (
    select * from ( values
         (1,4,1,0,0)
        ,(1,5,0,1,0)
        ,(1,6,0,0,1)
    )f(IncludeColumn,SecondInclude,Column1,Column2,Column3)
)

select
  orgid=boardname
  ,'B' as OrgType
  , Lang
  , BoardName
  ,cast(Null as varchar) as SchoolName

  ,SUM(Column1) as Column1
  ,SUM(Column2) as Column2
  ,SUM(Column3) as Column3

FROM TABLEB
CROSS APPLY f
WHERE [Include_Board] = 1 
  AND Table.IncludeColumn  = f.IncludeColumn
  AND TableB.SecondInclude = f.SecondInclude
Group By [Lang], BoardName
Run Code Online (Sandbox Code Playgroud)

现在表 f 可以(视情况而定)为:

  • 数据库中的永久表;或者
  • 应用程序定义的临时表;或者
  • 在存储过程中创建的表变量

这还有一个额外的优势,那就是数据驱动;如果您的屏蔽需要修改,则只需要更改数据而不需要更改代码。