0

This is a very basic SQL question. What I've got is a database for a garage with two tables: CARS and SERVICES. Each car is brought in for servicing once in a while, so each car can have multiple SERVICES records. Each record in SERVICES has a foreign key pointing to the related car, a date field and some additional info fields.

What I want is to get a list of cars with all the info from the most recent servicing. If I simply do

SELECT C.ID, S.*
FROM CARS C
JOIN SERVICES S ON S.CAR_ID = C.ID

Then I get a list of all cars with all services for each car (the Cartesian product of the two data sets). I'm using MS SQL Server.

4

2 回答 2

3

If you are using sql 2005+. Then you can do this:

;WITH CTE
AS
(
SELECT
    ROW_NUMBER() OVER(PARTITION BY CAR_ID 
                       ORDER BY theDateTimeColumn DESC) AS RowNbr,
    s.*
FROM
    SERVICES AS s
)
SELECT
    *
FROM
    CARS AS c
    JOIN CTE
        ON c.ID=CTE.CAR_ID 
        AND CTE.RowNbr=1

EDIT

If you want to have all the Cars that no matter if there has be serviced then you need to use a LEFT JOIN instead of a JOIN. Like this:

;WITH CTE
AS
(
SELECT
    ROW_NUMBER() OVER(PARTITION BY CAR_ID 
                       ORDER BY theDateTimeColumn DESC) AS RowNbr,
    s.*
FROM
    SERVICES AS s
)
SELECT
    *
FROM
    CARS AS c
    LEFT JOIN CTE
        ON c.ID=CTE.CAR_ID 
        AND CTE.RowNbr=1
于 2012-05-04T08:49:46.460 回答
2
SELECT
    CARS.ID,
    CARS.col2,
    ...,
    CARS.colm,
    SERVICES.SERVICE_TIME,
    ...,
    SERVICES.coln
FROM CARS
JOIN (
    SELECT A.CAR_ID, A.SERVICE_TIME, ..., A.coln
    FROM SERVICES AS A
    JOIN (
        SELECT CAR_ID, MAX(SERVICE_TIME) AS SERVICE_TIME
        FROM SERVICES
        GROUP BY CAR_ID
    ) AS B
    ON A.CAR_ID = B.CAR_ID
    AND A.SERVICE_TIME = B.SERVICE_TIME
) AS SERVICES
ON SERVICES.CAR_ID = CARS.ID
于 2012-05-04T08:48:49.157 回答