How to select latest appointment for a list of customers from Appointments table

  • Hey all,

    I realize this may seem like a basic question but it involves correlated sub-queries which I don't have a rigorous understanding of yet.

    Let's say there's an Appointments table for a hair salon. It contains two fields: CustomerId (int) and AppointmentDate (DateTime)

    I have a list of CustomerIds, and I want to select the customer ID and the latest appointment date for each customer in the list (let's say CustomerID's 1 through 5). How would I do this? I could look up the patients individually like this:

    SELECT * FROM Appointments

    WHERE CustomerId = 5

    ORDER BY AppointmentDate DESC

    I want to look up the latest appointment dates all at once. How would I do this? I would appreciate any help anyone can provide, especially since I think it would increase my understanding of SQL significantly. Thanks.

  • Try Max(http://msdn.microsoft.com/en-us/library/ms187751.aspx) Appointmentdate with group by(http://msdn.microsoft.com/en-us/library/ms177673.aspx) on customerid.

    Bob
    -----------------------------------------------------------------------------
    How to post to get the best help[/url]

  • SQLUserC (6/1/2012)


    Hey all,

    I realize this may seem like a basic question but it involves correlated sub-queries which I don't have a rigorous understanding of yet.

    Let's say there's an Appointments table for a hair salon. It contains two fields: CustomerId (int) and AppointmentDate (DateTime)

    I have a list of CustomerIds, and I want to select the customer ID and the latest appointment date for each customer in the list (let's say CustomerID's 1 through 5). How would I do this? I could look up the patients individually like this:

    SELECT * FROM Appointments

    WHERE CustomerId = 5

    ORDER BY AppointmentDate DESC

    I want to look up the latest appointment dates all at once. How would I do this? I would appreciate any help anyone can provide, especially since I think it would increase my understanding of SQL significantly. Thanks.

    Something like this.

    select

    CustomerId,

    max(AppointmentDate) as LatestDate

    from

    dbo.Appointments

    group by

    CustomerId

    order by

    CustomerId; -- Just to put them in some sort of order

  • I strongly suspect you will want to see more details on the last appointment than just the date:

    SELECT

    CustomerId, AppointmentDate, ...

    FROM (

    SELECT *, ROW_NUMBER() OVER(PARTITION BY CustomerId

    ORDER BY AppointmentDate DESC) AS row_num

    FROM dbo.Appointments a

    /*INNER JOIN dbo.ListOfCustIds lci ON lci.CustomerId = a.CustomerId*/

    WHERE CustomerId = 5 --for cust list, put in a table and join to it, as shown above

    ) AS derived

    WHERE

    row_num = 1

    ORDER BY

    CustomerId

    SQL DBA,SQL Server MVP(07, 08, 09) "It's a dog-eat-dog world, and I'm wearing Milk-Bone underwear." "Norm", on "Cheers". Also from "Cheers", from "Carla": "You need to know 3 things about Tortelli men: Tortelli men draw women like flies; Tortelli men treat women like flies; Tortelli men's brains are in their flies".

  • ScottPletcher (6/1/2012)


    I strongly suspect you will want to see more details on the last appointment than just the date:

    SELECT

    CustomerId, AppointmentDate, ...

    FROM (

    SELECT *, ROW_NUMBER() OVER(PARTITION BY CustomerId

    ORDER BY AppointmentDate DESC) AS row_num

    FROM dbo.Appointments a

    /*INNER JOIN dbo.ListOfCustIds lci ON lci.CustomerId = a.CustomerId*/

    WHERE CustomerId = 5 --for cust list, put in a table and join to it, as shown above

    ) AS derived

    WHERE

    row_num = 1

    ORDER BY

    CustomerId

    Maybe, then you could also do this:

    select

    a.* -- to save time, should define all columns you want to return

    from

    dbo.Appointments a

    inner join (

    select

    CustomerId,

    max(AppointmentDate) as LatestDate

    from

    dbo.Appointments

    group by

    CustomerId

    )dt

    on (a.CustomerId = dt.CustomerId and a.AppointmentDate = dt.LatestDate)

    order by

    a.CustomerId;

  • Maybe, then you could also do this:

    select

    a.* -- to save time, should define all columns you want to return

    from

    dbo.Appointments a

    inner join (

    select

    CustomerId,

    max(AppointmentDate) as LatestDate

    from

    dbo.Appointments

    group by

    CustomerId

    )dt

    on (a.CustomerId = dt.CustomerId and a.AppointmentDate = dt.LatestDate)

    order by

    a.CustomerId;

    I'd have done that on SQL 7.0 or SQL 2000; on SQL 2005+, the windowing functions are much easier -- and faster.

    SQL DBA,SQL Server MVP(07, 08, 09) "It's a dog-eat-dog world, and I'm wearing Milk-Bone underwear." "Norm", on "Cheers". Also from "Cheers", from "Carla": "You need to know 3 things about Tortelli men: Tortelli men draw women like flies; Tortelli men treat women like flies; Tortelli men's brains are in their flies".

  • Thanks very much for these replies. They gave me some useful stuff to research.

  • ScottPletcher (6/1/2012)


    Maybe, then you could also do this:

    select

    a.* -- to save time, should define all columns you want to return

    from

    dbo.Appointments a

    inner join (

    select

    CustomerId,

    max(AppointmentDate) as LatestDate

    from

    dbo.Appointments

    group by

    CustomerId

    )dt

    on (a.CustomerId = dt.CustomerId and a.AppointmentDate = dt.LatestDate)

    order by

    a.CustomerId;

    I'd have done that on SQL 7.0 or SQL 2000; on SQL 2005+, the windowing functions are much easier -- and faster.

    The last time I posted something similar to this using the row_number() function, someone else came along and posted the group by solution. Always seems to be more than one way to do things.

Viewing 8 posts - 1 through 7 (of 7 total)

You must be logged in to reply to this topic. Login to reply