简体   繁体   中英

How to count rows based on date in SQL Server?

I have table of dates:

在此处输入图像描述

I want to display how many rows by counting the rows between 2019-06-30 to 2020-03-30 base on the table? the output should be 10 rows. I tried

SELECT ln.datestart,
       ln.loanid,
       col.IDNo,
       ls.LoanID,
       max(CAST(col.DateOR AS date)) AS lastpayment,
       COUNT(ls.loanid) AS rowcount
FROM Collections AS col
INNER JOIN LoanSchedules AS ls ON ls.LoanID = col.IDNo
INNER JOIN Loans AS ln ON ln.LoanID = ls.LoanID
WHERE ls.DatePayment BETWEEN ln.DateStart AND max(col.DateOR)
GROUP BY ln.loanid,
         col.IDNo,
         ls.LoanID,
         ln.datestart

but it returns an error saying:

An aggregate may not appear in the WHERE clause unless it is in a subquery contained in a HAVING clause or a select list, and the column being aggregated is an outer reference.

ps: ln.datestart is from another table that records the 1st payment schedule of each client. i use max(dateor) from an another table to know the last date of the payment.

You have to use having clause while filtering with aggregated columns,

select ls.DatePayment, ln.datestart,ln.loanid,col.IDNo, ls.LoanID, max(CAST(col.DateOR as date)) as 
lastpayment,
COUNT(ls.loanid) as rowcount

from Collections as col
inner join LoanSchedules as ls 
on ls.LoanID = col.IDNo
inner join Loans as ln
on ln.LoanID = ls.LoanID
group by ls.DatePayment, ln.loanid,col.IDNo,ls.LoanID,ln.datestart
having ls.DatePayment between ln.DateStart and max(col.DateOR)

it's not crystal clear to me what the result you want to achieve is, but I guess you need to use the apply operator. I tried to reproduce your case and here you have the result:

create table #LOANS(
             LoanId           char(11) not null
            ,DatePayment      date not null
            ,PrincipalPayment numeric(11,2) not null
            ,InterestPayment  numeric(11,2) not null
            ,TotalPayment     numeric(11,2) not null
)

insert into #LOANS (LoanId, DatePayment, PrincipalPayment, InterestPayment, TotalPayment)
            values ('B 1905.0005', '2019-06-30', '5833.33', '2106.67', '7490.00')
                  ,('B 1905.0005', '2019-07-30', '5833.33', '2106.67', '7490.00')
                  ,('B 1905.0005', '2019-08-30', '5833.33', '2106.67', '7490.00')
                  ,('B 1905.0005', '2019-09-30', '5833.33', '2106.67', '7490.00')
                  ,('B 1905.0005', '2019-10-30', '5833.33', '2106.67', '7490.00')
                  ,('B 1905.0005', '2019-11-30', '5833.33', '2106.67', '7490.00')
                  ,('B 1905.0005', '2019-12-30', '5833.33', '2106.67', '7490.00')
                  ,('B 1905.0005', '2020-01-30', '5833.33', '2106.67', '7490.00')
                  ,('B 1905.0005', '2020-02-29', '5833.33', '2106.67', '7490.00')
                  ,('B 1905.0005', '2020-03-30', '5833.33', '2106.67', '7490.00')
                  ,('B 1905.0005', '2020-04-30', '5833.33', '2106.67', '7490.00')
                  ,('B 1905.0005', '2020-05-30', '5833.33', '2106.67', '7490.00')

select *
from   #LOANS l
       outer apply(select   COUNT(*) as rowNr
                   from     #LOANS ll
                   where    ll.LoanId = l.LoanId
                        and ll.DatePayment between '2019-06-30' and '2020-03-30'
                   group by LoanId) c

https://i.stack.imgur.com/9hxpc.png

Your logic is a hard to follow. You show one table of data, but your query references three tables. I'm pretty sure, though, that you can use a window function to do what you want. It is just unclear which window function you want. I think:

SELECT datestart, loanid, cIDNo, LoanID,
       COUNT(*) AS rowcount
FROM (SELECT ln.datestart, ln.loanid, col.IDNo, ls.LoanID, ls.DatePayment,
             MAX(CAST(col.DateOR AS date)) OVER (PARTITION BY ln.datestart, ln.loanid, col.IDNo, ls.LoanID) as max_DateOR
      FROM Collections col JOIN
           LoanSchedules ls
           ON ls.LoanID = col.IDNo JOIN
           Loans ln
           ON ln.LoanID = ls.LoanID
     ) x
WHERE DatePayment BETWEEN ln.DateStart AND max_DateOR
GROUP BY loanid, IDNo, LoanID, datestart;

This assumes that you are looking for the maximum based on the four group by keys.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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