使查询更短,精炼和优化

时间:2014-09-25 15:34:03

标签: sql sql-server-2008 tsql

我有这个查询工作正常,但在它和每个查询中都有重复(重复),仅来自"其中"陈述和"和"声明变更

我想知道我是否可以通过缩短下面的查询(更少的代码)或者换句话说优化它来产生相同的结果。任何人吗?

DECLARE @Queued int;
set @Queued = ( 
            select count(STATENAME)as Queued 
from   [EAC].[MessageStore].[MessageProcessingAttemptState] a inner JOIN 
 [EAC].[MessageStore].[MessageProcessingAttempt]  b
ON a.MessageProcessingAttemptStateID = b.MessageProcessingAttemptStateID
inner join [EAC].[MessageStore].[Message] c
 on b.MessageID = c.MessageID
Where a.MessageProcessingAttemptStateID = '1'
and c.MessageGroupId = '44'
and b.QueuedTime BETWEEN '2014-09-12' AND '2014-09-16')

Declare @Scheduled int;
set @Scheduled =
(select count(STATENAME)as Scheduled 
from   [EAC].[MessageStore].[MessageProcessingAttemptState] a inner JOIN 
 [EAC].[MessageStore].[MessageProcessingAttempt] b
ON a.MessageProcessingAttemptStateID = b.MessageProcessingAttemptStateID
inner join [EACatalog2013].[MessageStore].[Message] c
 on b.MessageID = c.MessageID
WHERE a.MessageProcessingAttemptStateID = '2'
and c.MessageGroupId = '44'
and b.QueuedTime BETWEEN '2014-09-12' AND '2014-09-16')

Declare @NotCompleted int;
set @NotCompleted = @Queued + @Scheduled

DECLARE @Queued1 int;

set @Queued1 = ( 
            select count(STATENAME)as Queued 
from   [EAC].[MessageStore].[MessageProcessingAttemptState] a inner JOIN 
 [EAC].[MessageStore].[MessageProcessingAttempt]  b
ON a.MessageProcessingAttemptStateID = b.MessageProcessingAttemptStateID
inner join [EACatalog2013].[MessageStore].[Message] c
 on b.MessageID = c.MessageID
Where a.MessageProcessingAttemptStateID = '1'
and c.MessageGroupId = '45'
and b.QueuedTime BETWEEN '2014-09-12' AND '2014-09-16')

Declare @Scheduled1 int;
set @Scheduled1 =
(select count(STATENAME)as Scheduled 
from   [EAC].[MessageStore].[MessageProcessingAttemptState] a inner JOIN 
 [EAC].[MessageStore].[MessageProcessingAttempt]  b
ON a.MessageProcessingAttemptStateID = b.MessageProcessingAttemptStateID
inner join [EACatalog2013].[MessageStore].[Message] c
 on b.MessageID = c.MessageID
WHERE a.MessageProcessingAttemptStateID = '2'
and c.MessageGroupId = '45'
and b.QueuedTime BETWEEN '2014-09-12' AND '2014-09-16')

Declare @NotCompleted1 int;
set @NotCompleted1 = @Queued1 + @Scheduled1

select @NotCompleted as NotCompleted
union
select @NotCompleted1 as NotCompleted

2 个答案:

答案 0 :(得分:1)

如果你可以返回一个简单的单行,那么这个怎么样..它会在一个消息组44或45中获得一次传递所有数据,而在日期中仅获得状态1或2。

通过执行SUM(逻辑条件),如果逻辑条件为真,则计为1,否则为0.

因此,通过条件限定组和状态允许简单的1行,其中4列各自排队和排定。现在,如果您需要它们之间的差异(净值),只需根据需要减去。

SELECT
      SUM( case when c.MessageGroupId = '44' AND a.MessageProcessingAttemptStateID = '1' then 1 else 0 end ) as Queued,
      SUM( case when c.MessageGroupId = '44' AND a.MessageProcessingAttemptStateID = '2' then 1 else 0 end) as Scheduled,
      SUM( case when c.MessageGroupId = '45' AND a.MessageProcessingAttemptStateID = '1' then 1 else 0 end) as Queued1,
      SUM( case when c.MessageGroupId = '45' AND a.MessageProcessingAttemptStateID = '2' then 1 else 0 end) as Scheduled1
   from
      [EAC].[MessageStore].[MessageProcessingAttemptState] a 
         inner JOIN [EAC].[MessageStore].[MessageProcessingAttempt] b
            ON a.MessageProcessingAttemptStateID = b.MessageProcessingAttemptStateID
            inner join [EAC].[MessageStore].[Message] c
               on b.MessageID = c.MessageID
   Where 
          a.MessageProcessingAttemptStateID IN ( '1', '2' )
      and c.MessageGroupId IN ( '44', '45' )
      and b.QueuedTime BETWEEN '2014-09-12' AND '2014-09-16'

答案 1 :(得分:-1)

我会编写一个没有where子句的查询,并将其插入表中。然后编写4个简短而简洁的查询来获取实际数据。以下是前两个查询的示例。

select count(STATENAME)as Queued,
    a.MessageProcessingAttemptStateID as MessageProcessingAttemptStateID,
    c.MessageGroupId as MessageGroupId,
    b.QueuedTime as QueuedTime
into table_1
from   [EAC].[MessageStore].[MessageProcessingAttemptState] a 
    inner JOIN [EAC].[MessageStore].[MessageProcessingAttempt]  b
        ON a.MessageProcessingAttemptStateID = b.MessageProcessingAttemptStateID
    inner join [EAC].[MessageStore].[Message] c
        on b.MessageID = c.MessageID


select t.Queued, t.MessageProcessingAttemptStateID
from table_1 t
where MessageProcessingAttemptStateID = '1'
    and MessageGroupId = '44'
    and QueuedTime BETWEEN '2014-09-12' AND '2014-09-16'

select t.Queued, t.MessageProcessingAttemptStateID
from table_1 t
where MessageProcessingAttemptStateID = '2'
    and MessageGroupId = '44'
    and QueuedTime BETWEEN '2014-09-12' AND '2014-09-16'

它会更快,因为而不是这样做

from   [EAC].[MessageStore].[MessageProcessingAttemptState] a 
    inner JOIN [EAC].[MessageStore].[MessageProcessingAttempt]  b
        ON a.MessageProcessingAttemptStateID = b.MessageProcessingAttemptStateID
    inner join [EAC].[MessageStore].[Message] c
        on b.MessageID = c.MessageID

四次,编译器会做一次。此外,它更具可读性,并且更容易发现差异。

注意:对某些人而言,这将是微不足道的,但为了注意您不需要在数据库中使用table_1。实际上,您的数据库中不应该有一个名为table_1的表。如果这样做,只需将此查询中的table_1更改为其他名称即可。如果你想知道为什么那么它很简单。当您使用这种类型的语法时,编译器会创建一个名为table_1的表,该表具有您尝试插入的列,并且这些列具有相同的数据类型。

编辑: 在你第一次跑步后改变这个想法吧。

select count(STATENAME)as Queued,
    a.MessageProcessingAttemptStateID as MessageProcessingAttemptStateID,
    c.MessageGroupId as MessageGroupId,
    b.QueuedTime as QueuedTime
into table_1

insert into table_1
select count(STATENAME)as Queued,
        a.MessageProcessingAttemptStateID as MessageProcessingAttemptStateID,
        c.MessageGroupId as MessageGroupId,
        b.QueuedTime as QueuedTime