I have a table that has many records and duplicate IDs. I'm trying to group by each ID and show the record with the latest date. Only one ID should show and it should be the record with the latest date. I have done that in the below query and I have put this query into a View in SQL Server:
Pymt_View:
SELECT MAX(CONVERT(datetime, pmt_dt)) AS PymtDate, id_no AS ID, MAX(CONVERT(datetime, due_dt))
AS PymtDueDate, pmt_cd
FROM Payment_Table
WHERE (CONVERT(datetime, due_dt) <= GETDATE()) AND (pmt_cd = '999') AND (amount > 0)
GROUP BY ID, pmt_cd
Then I use this View in a new query to join on the original Payment_Table to grab the columns I need based off the matching of columns in the join. I am using the View as my left table and the original payment table as my right.
New Query With View as the Left Table:
select a.PymtDate, a.[ID], a.PymtDueDate, b.amount, b.pmt_cd, b.batch_no
from Pymt_View a left join Payment_Table b on (a.ID = b.ID) and a.PymtDate = cast(b.pmt_dt as
datetime) and a.pmt_cd = b.pmt_cd)
order by a.[ID] asc, PymtDate desc, PymtDueDate desc
This produces the results I need. However, I am curious how I can do this in one query/view without having to create the Pymt_View? I have tried the following code in an attempt to subquery the grouped population I need and left join it onto the table to grab the columns I need that I was unable to grab from the group by query. I need the b.amount, b.pmt_cd, b.batch_no columns, but couldn't get them through with the group by
select x.*,
from (
SELECT MAX(CONVERT(datetime, pmt_dt)) AS PymtDate, id_no AS ID, MAX(CONVERT(datetime, due_dt))
AS PymtDueDate, pmt_cd
FROM Payment_Table
WHERE (CONVERT(datetime, due_dt) <= GETDATE()) AND (pmt_cd = '999') AND (amount > 0)
GROUP BY ID, pmt_cd
) x left join Payment_Table on (a.ID = b.ID) and a.PymtDate = cast(b.pmt_dt as datetime) and a.pmt_cd
= b.pmt_cd)
This doesn't work. Eventually, if I am able to get the population that I need from the payment_table without having to use the pymt_view. I would then need to join that query with another population, so I would have to create a View again that would be used in another View. Is there any way to get around having to create Views and use them as tables? I would like all this to be in one query that I can put into a View. Without having to create more views to be used in a View. I hope to do this in just one View.
Thank you for your assistance.
You can do this with a row-numbering solution very efficiently:
SELECT
CONVERT(datetime, pmt_dt) PymtDate,
p.[ID],
CONVERT(datetime, due_dt) PymtDueDate,
p.amount,
p.pmt_cd,
p.batch_no
from (
SELECT *,
ROW_NUMBER() OVER (PARTITION BY ID, pmt_cd ORDER BY CONVERT(datetime, pmt_dt) DESC) AS rn
FROM Payment_Table
WHERE (CONVERT(datetime, due_dt) <= GETDATE()) AND (pmt_cd = '999') AND (amount > 0)
) p
WHERE rn = 1
order by a.[ID] asc, PymtDate desc, PymtDueDate desc