简体   繁体   English

根据SQL Server中的条件对行进行计数

[英]Counting rows based on a criteria in sql server

I have an example data as follows: 我有一个示例数据,如下所示:

field1  onlineoffline   trxndate
--------------------------------
F1       Offline        2018-04-03
F1       Online         2018-04-04
F1       Online         2018-04-05
F1       Offline        2018-04-06
F1       Offline        2018-04-07
F1       Offline        2018-04-08
F1       Offline        2018-04-09
F1       Online         2018-04-10
F1       Offline        2018-04-11

I need to get count of records which are online after 1st online based on the trxndate(which is 2 in this example), also I want to get count of all the records after 1st online record based on the trxndate(7 in this example) in a single query. 我需要基于trxndate(在此示例中为2)获得第一次在线记录后在线记录的计数,也想基于trxndate(在此示例中为7)获得第一次在线记录后所有记录的计数。在一个查询中。

I tried using the row_number() but didn't quite get to the point. 我尝试使用row_number(),但并没有达到目的。 Is there a way to get this. 有没有办法做到这一点。

Is this what you want? 这是你想要的吗?

select count(*) as num_records,
       sum(case when onlineoffline = 'online' then 1 else 0 end) as num_online_record
from (select t.*,
             min(case when onlineoffline = 'online' then trxndate end) over () as min_online_td
      from t
     ) t
where trxndate > min_online_td;

The subquery calculates the date for the first online record. 子查询计算第一个在线记录的日期。 The rest of the query just does the counts that you want. 查询的其余部分仅执行所需的计数。

select  -- count only Online rows
        online_count = sum(case when onlineoffline = 'Online' then 1 else 0 end),
        -- count all rows
        all_count = count(*)
from    tbl
where   trxdate >   
        -- find the first trxdate that is online
        (select top 1 trxdate from tbl where onlineoffline = 'Online' order by trxdate)

Determine the first online date, then do 2 counts. 确定第一个在线日期,然后进行两次计数。

;WITH MinimumOnlineDate AS
(
    SELECT
        MinDate = MIN(T.trxndate)
    FROM
        YourTable AS T
    WHERE
        T.onlineoffline = 'Online'
)
SELECT
    TotalAfterFirstOnline = COUNT(1),
    TotalOnlineAfterFirstOnline = COUNT(CASE WHEN T.onlineoffline = 'Online' THEN 1 END)
FROM
    YourTable AS T
    INNER JOIN MinimumOnlineDate AS M ON T.trxndate > M.MinDate

other option is to do with correlation subquery 另一种选择是与相关 subquery

select count(*) as online_counts, max(t1.counts) as no_of_onlines
from table t
join (
    select distinct min(trxndate) over() trxndate, count(*) over (order by field1) Counts 
    from table t
    where onlineoffline = 'Online' and trxndate <> (
          select min(trxndate) from table where onlineoffline = 'Online' and field1 = t.field1) 
)t1 on t.trxndate >= t1.trxndate
select
    sum(case when onlineoffline = 'Online' then 1 else 0 end) online,
    count(*) all 
from    table
where   trxdate > (select top 1 trxdate from table where onlineoffline = 'Online' order by trxdate)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM