T-SQL选择条件连接

时间:2013-03-26 14:03:33

标签: sql-server tsql join max

假设我有3张桌子:

  1. 汽车

    • 编号
  2. CarColorHistory

    • 编号
    • CarID
    • ColorID
    • 时间modificationdate
  3. 颜色

    • 编号
    • ColorName
  4. 我想选择所有汽车及其颜色,但重要的是,汽车的颜色是CarColorHistory表中的最后修改颜色。

    我需要使用join来执行此操作。

    示例:

    汽车:

    1
    2
    

    CarColorhistory:

    1 1 1 26/03/2012  -> (actual color, can be take by date or id)
    2 1 2 25/03/2012
    3 2 2 25/03/2012
    

    颜色

    1 Blue
    2 Red
    

    我需要得到结果:(car id,colorName)

    1 Blue
    2 Red
    

    我尝试通过加入Cars table和CarColorHistory表来制作它,但我得到所有颜色的汽车。我只需要实际颜色(最后添加)。

    请帮忙

6 个答案:

答案 0 :(得分:4)

试试这个:

select c.id, colorname
from cars c
inner join CarColorHistory h on c.id = h.CarID
inner join Color c2 on h.colorid = c2.id
where h.ModificationDate = (select max(ModificationDate)
                            from CarColorHistory x where c.id = x.CarId)

答案 1 :(得分:3)

有几种方法可以获得结果。您可以使用子查询来获取max(modificationdate)

select c.id, r.colorname
from cars c
inner join CarColorhistory h1
  on c.id = h1.carid
inner join
(
  select max(modificationdate) MaxDate,
    carid
  from CarColorhistory
  group by carid
) h2
  on h1.carid = h2.carid
  and h1.modificationdate = h2.maxdate
inner join color r
  on h1.colorid = r.id

请参阅SQL Fiddle with Demo

或者,由于您使用的是SQL Server,因此可以使用ranking functions

select id, colorname
from
(
  select c.id, r.colorname,
    row_number() over(partition by c.id order by modificationdate desc) rn
  from cars c
  inner join CarColorhistory h1
    on c.id = h1.carid
  inner join color r
    on h1.colorid = r.id
) src
where rn = 1;

请参阅SQL Fiddle with Demo

答案 2 :(得分:1)

这应该适合你:

SELECT c.id, (
    SELECT co.ColorName FROM Color co
    WHERE co.id = (
        SELECT TOP 1 ColorID FROM CarColorHistory
        WHERE CarID = c.id
        ORDER BY ModificationDate DESC
    )
 ) AS ColorName

答案 3 :(得分:0)

这样做的一种方法可能就是使用子查询,比如之前发布的,因为你使用的是t-sql,你也应该能够使用apply:

SELECT
        Cars.Id, LatestColors.ColorID, LatestColors.ModificationDate
    FROM Cars
    CROSS APPLY (
        SELECT TOP 1
                ColorID, ModificationDate
            FROM CarColorHistory
            WHERE CarID = Cars.ID
            ORDER BY ModificationDate DESC
    ) AS LatestColors

答案 4 :(得分:0)

如果您有Sql Server 2005或更高版本,可以试试这个:

您可以在此处尝试Common table expression的工作方式:Sql Fiddle demo

  ;WITH CTE_Cars(CarID, MaxDate)
    AS
    (
    SELECT CarID, MAX(ModificataionDate) AS MaxDate
    FROM CarColorHistory
    GROUP BY CarID
    )
    SELECT CTE_Cars.CarID, Color.ColorName
    FROM 
    CTE_Cars
    INNER JOIN CarColorHistory ON CarColorHistory.CarID = CTE_Cars.CarID AND
    CarColorHistory.ModificataionDate = CTE_Cars.MaxDate
    INNER JOIN Color ON Color.id = CarColorHistory.ColorId

答案 5 :(得分:0)

我不确定这是不是最好的方法,但这就是我这样做的方式。首先使用MAX从表中获取所需的值,然后将该结果用作JOIN的表,以消除不需要的值。

SELECT c.ID, Color.Color
From Cars c JOIN CarColorHistory h on c.id = h.CarID
     JOIN Color on h.ColorID = Color.ID
     JOIN

    --Create a table with only the latest value and the car ID
    ( 
    SELECT c.ID, Max(h.TimeStamp) as time
    FROM Cars c JOIN CarColorHistory h on c.id = h.CarID
         JOIN Color on h.ColorID = Color.ID
    Group by c.ID --Join the table on latest time to get rid of old timestamps
    ) Max on Max.ID = c.ID and h.TimeStamp=max.time