我正在努力形成一个返回不同类型对象的最新记录的查询。我创建了以下示例,显示了我想要实现的目标。
表格
CREATE TABLE Fruit
(
ID [int] PRIMARY KEY IDENTITY (1,1) NOT NULL,
Name [nvarchar](20) NOT NULL
)
CREATE TABLE Bites
(
ID [int] PRIMARY KEY IDENTITY (1,1) NOT NULL,
FruitID [int] FOREIGN KEY REFERENCES Fruit(ID) NOT NULL,
BittenOn [datetime] NOT NULL
)
现在填充一些测试数据。
INSERT INTO Fruit VALUES ( 'Apple' );
INSERT INTO Fruit VALUES ( 'Orange' );
INSERT INTO Fruit VALUES ( 'Strawberry' );
INSERT INTO Bites VALUES ( 1, '2014/2/20 12:30:00' );
INSERT INTO Bites VALUES ( 2, '2014/2/20 12:31:00' );
INSERT INTO Bites VALUES ( 2, '2014/2/20 12:32:00' );
INSERT INTO Bites VALUES ( 3, '2014/2/20 12:33:00' );
INSERT INTO Bites VALUES ( 3, '2014/2/20 12:34:00' );
INSERT INTO Bites VALUES ( 3, '2014/2/20 12:35:00' );
INSERT INTO Bites VALUES ( 1, '2014/2/20 12:40:00' );
INSERT INTO Bites VALUES ( 3, '2014/2/20 12:40:00' );
我希望我的查询返回每个水果被咬的最新日期。 我尝试了以下方法:
SELECT
F.Name,
B.BittenOn as LastBittenOn
FROM
Fruit as F
INNER JOIN
Bites as B ON B.BittenOn = ( SELECT MAX(BittenOn) FROM Bites )AND B.FruitID=F.ID
但我只收到苹果和草莓,因为他们分享了最新的咬合日期,但我也希望Orange有日期/时间'2014 / 2/20 12:32:00'。
有人可以帮我处理所需的查询吗?
安迪
答案 0 :(得分:1)
像
这样的东西SELECT f.Name,
b.BittenOn
FROM Fruit as F OUTER APPLY
(
SELECT TOP 1 *
FROM Bites b
WHERE b.FruitID = f.ID
ORDER BY b.BittenOn DESC
) b
另一种选择是
;WITH BitesCTE AS (
SELECT FruitID,
MAX(BittenOn) BittenOn
FROM Bites
GROUP BY FruitID
)
SELECT f.Name,
b.BittenOn
FROM Fruit f LEFT JOIN
BitesCTE b ON f.ID = b.FruitID
答案 1 :(得分:0)
SELECT
F.Name,
B.BittenOn as LastBittenOn
FROM
Fruit as F
INNER JOIN
( SELECT ROW_NUMBER()OVER(PARTITION BY FruitID ORDER BY BittenOn DESC) AS row_num
,FruitID
,BittenOn
FROM Bites
) B
ON F.ID = B.FruitID
AND B.row_num = 1
答案 2 :(得分:0)
另一种选择是上述的旁观者答案:
SELECT f.Name,
b.BittenOn
FROM Fruit as F OUTER APPLY
(
SELECT MAX(b.BittenOn) as BittenOn
FROM Bites b
WHERE b.FruitID = f.ID
GROUP BY b.FruitID
) b
根据索引,它可能会更快,因为它消除了昂贵的排序。当我运行原始版本和更改版本时,执行计划建议查询成本为14%对86%(相对于批处理),支持使用max()
。
编辑:另一个版本根据评论中的要求提供不同的输出:
SELECT LastBites.FruitID, Bites.ID
FROM Bites
INNER JOIN (
SELECT b.FruitID, MAX(b.BittenOn) as BittenOn
FROM Bites b
GROUP BY b.FruitID
) LastBites ON Bites.BittenOn = LastBites.BittenOn AND Bites.FruitID = LastBites.FruitID
ORDER BY LastBites.FruitID ASC