Sql选择发送和接收的计数

时间:2013-05-30 01:56:13

标签: sql sql-server tsql join subquery

我需要为发送和接收的交易编写查询报告。

Status_Id      Status_dt       Status
1               4/1/2013       sent
1               4/1/2013       sent
2               4/2/2013       sent
3               4/3/2013       sent
1               4/1/2013       Received
1               4/4/2013       Received  
2               4/4/2013       received

可以在任何日期收到特定日期发送的交易。

从上面

在2013年4月1日发送的交易是两个(对于id 1),并且这个id wch是在2013年4月1日发送的,已于2013年4月1日和2013年4月4日收到

所以o / p应该是

dt              sent_count          received_count
4/1/2013          2                       2

在2013年4月2日发送的交易是一个(对于ID 2),对于这个id wch发送于2013年4月2日已收到2013年4月4日

所以o / p应该是

dt              sent_count          received_count
4/2/2013          1                       1

在2013年4月3日发送的交易是一个(对于ID 3)并且对于这个id wch是在2013年4月3日发送还没有收到

所以o / p应该是

dt              sent_count          received_count
4/3/2013          1                       0

因此,如果我在2013年4月5日运行查询,则输出应为:::

dt              sent_count          received_count
4/1/2013          2                       2 
4/2/2013          1                       1 
4/3/2013          1                       0

对于已发送的计数,我可以将查询写为:

select status_dt, count(*)
from table
where status = 'sent'
group by status_dt

我应该为收到的计数写什么查询?

2 个答案:

答案 0 :(得分:2)

对于收到的,您需要加入返回发送日期。如果状态ID是唯一的,那么这将是查询:

select t.status_dt, count(*)
from table t join
     table tres
     on t.status_id = tres.status_id and
        t.status = 'sent' and
        tres.status = 'received'
group by status_dt;

相反,一种方法是分配唯一的ID:

select t.status_dt, count(*) as SentCount, count(tres.status_id) as ReceivedCount
from (select t.*,
             row_number() over (partition by status_id order by status_dt) as seqnum
      from table t
      where tres.status = 'sent'
     ) t join
     (select tres.*,
             row_number() over (partition by status_id order by status_dt) as seqnum
      from table tres
      where tres.status = 'received'
     ) tres
     on t.status_id = tres.status_id and
        t.seqnum = tres.seqnum
group by status_dt;

此唯一ID根据记录中的日期(分别针对已发送和已接收的日期)枚举给定status_id的所有内容。这是有效的,因为收到的总是在发送之后。所以,第n次接收总是在第n次发送之后。

如果您想在一个查询中同时使用SentCount和ReceivedCount:

select t.status_dt, count(*) as SentCount, count(tres.status_id) as ReceivedCount
from (select t.*,
             row_number() over (partition by status_id order by status_dt) as seqnum
      from table t
      where tres.status = 'sent'
     ) t left outer join
     (select tres.*,
             row_number() over (partition by status_id order by status_dt) as seqnum
      from table tres
      where tres.status = 'received'
     ) tres
     on t.status_id = tres.status_id and
        t.seqnum = tres.seqnum
group by status_dt;

答案 1 :(得分:0)

试试这个,

select t1.Status_dt, 
       (select count(t2.Status) from table t2 where t2.Status='sent' and t1.Status_dt = t2.Status_dt) as sent_count,
       (select count(t2.Status) from table t2 where t2.Status='received' and t1.Status_dt = t2.Status_dt) as received_count
    from table t1 group by t1.Sattus_dt