简化此查询,我确信有更好的方法(从多个UNION ALL中选择)

时间:2014-02-08 16:35:26

标签: sql performance union

这是我当前的查询,它有效,但看起来并不优雅。 不幸的是,这些表尚未规范化,我需要通过四个不同的代码字段从4个单独的数字字段中获取总和。 代码字段包含某人的姓名,同一名称可能会也可能不会出现在四个代码字段的每一个中。 因此,我想在CODE 2,3,4,5中总结所有出现的名称,总计相应的Numb 2,3,4,5字段。

Select Organisation, code, sum(numb)as mynumb
from
(
(Select organisation, code2 as code, numb2 as numb 
    from dbo.continfo ci 
    join dbo.conthist ch on ci.pvkey = ch.pvkey
    where Not code2 is Null)
UNION ALL
(Select organisation, code3 as code, numb3 as numb 
    from dbo.continfo ci 
    join dbo.conthist ch on ci.pvkey = ch.pvkey
    where Not code3 is Null)
UNION ALL
(Select organisation, code4 as code, numb4 as numb 
    from dbo.continfo ci 
    join dbo.conthist ch on ci.pvkey = ch.pvkey
    where Not code4 is Null)
UNION ALL
(Select organisation, CODE5 as code, NUMB5 as numb 
    from dbo.continfo ci 
    join dbo.conthist ch on ci.pvkey = ch.pvkey
    where Not CODE5 is Null)
) as f
GROUP BY Organisation, code
ORDER BY mynumb desc

任何帮助表示感谢。

2 个答案:

答案 0 :(得分:1)

您可以通过取消数据来提高效率。我更喜欢使用cross join子句中的caseselect语句明确地执行unpivot:

select organization, code, sum(numb)
from (Select organisation,
             (case when n.n = 1 then code1
                   when n.n = 2 then code2
                   when n.n = 3 then code3
                   when n.n = 4 then code4
                   when n.n = 5 then code5
              end) as code, 
             (case when n.n = 1 then numb1
                   when n.n = 2 then numb2
                   when n.n = 3 then numb3
                   when n.n = 4 then numb4
                   when n.n = 5 then numb5
              end) as numb
      from dbo.continfo ci join
           dbo.conthist ch
           on ci.pvkey = ch.pvkey cross join
           (select 1 as n union all select 2 union all select 3 union all select 4 union all select 5
           ) n
     ) t
where code is not null;

这应该从连接生成一次数据,并为结果集中的每一个创建五行,每个代码一个。

这样做的难度表明为什么你真的想要另一个关联/联结表。每个pvkeycode会有一行。如果您有这样的表,则此查询将是一个简单的连接和聚合。

答案 1 :(得分:-1)

大多数RDBM都有命令向您显示优化查询的结果。检查一下它告诉你什么,并决定是否值得你手工烧掉它。