使用1-N关系连接表

时间:2012-05-04 08:44:31

标签: sql sql-server one-to-many

这是一个非常基本的SQL问题。我得到的是一个带两张桌子的车库数据库:CARS and SERVICES。每辆车都会暂时停放服务,因此每辆车都可以有多个服务记录。 SERVICES中的每条记录都有一个指向相关汽车的外键,一个日期字段和一些其他信息字段。

我想要的是获取包含最近服务中所有信息的汽车列表。如果我只是做

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

然后我得到所有汽车的列表,其中包含每辆车的所有服务(两个数据集的笛卡尔积)。我正在使用MS SQL Server。

2 个答案:

答案 0 :(得分:3)

如果您使用的是sql 2005+。然后你可以这样做:

;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

修改

如果你想拥有所有的汽车,无论是否有服务,你需要使用LEFT JOIN而不是JOIN。像这样:

;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

答案 1 :(得分: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