我有两个名为Test的表,TestHistory中的testHistory与测试有FK关系。
现在我想从表TestHistory中选择带有测试表记录的Top 1 Inserted数据。
我想要的输出是:
或者我的TestHistory表没有必要有与TestId相关的记录,那么我的输出将是:
我用子查询实现了这一点,如:
Select Id,(select top(1) price from TestHistory HT Where T.Id=HT.TestId order by HT.Id desc) As Price
From Test T
但我不想使用子查询。 我想在没有子查询的情况下选择数据。
如果没有Sub查询,请建议我如何做到这一点,这将是解决此问题的最佳替代方法。
答案 0 :(得分:1)
我认为最简单的方法是使用row_number()
来获得结果,但仍然会有子查询。但这不是一个相关的子查询:
select id, price, testhistoryid
from
(
select t.id,
h.price,
h.id testhistoryid,
row_number() over(partition by t.id order by h.id desc) rn
from test t
inner join testhistory h
on t.id = h.testid
) src
where rn = 1;
如果您想要返回历史记录表中不存在的test
行,那么您将使用LEFT JOIN
代替INNER JOIN
:
select id, price, testhistoryid
from
(
select t.id,
h.price,
h.id testhistoryid,
row_number() over(partition by t.id order by h.id desc) rn
from test t
left join testhistory h
on t.id = h.testid
) src
where rn = 1;
请参阅Demo
答案 1 :(得分:0)
对不起,但如果没有某种子查询,没有真正的方法可以做到这一点。你写的查询很好。在我看来,实现你所寻找的最佳语法是:
SELECT
T.ID,
HT.*
FROM
dbo.Test T
OUTER APPLY (
SELECT TOP 1 *
FROM dbo.TestHistory HT
WHERE T.ID = HT.TestID
ORDER BY HT.ID DESC
) HT
;
Try this out yourself in a SQL Fiddle
如果您想限制它,那么只显示具有匹配Test
行的TestHistory
行,然后使用CROSS APPLY
代替OUTER APPLY
。
此外,这样的查询是可能的,也许更容易理解,但很可能不会那么好,而且它要求每个TestHistory
行至少有一个Test
行
SELECT
T.ID,
HT.*
FROM
dbo.Test T
INNER JOIN dbo.TestHistory HT
ON T.ID = HT.TestID
WHERE
HT.ID = (
SELECT Max(HT2.ID)
FROM dbo.TestHistory HT2
WHERE T.ID = HT2.TestID
)
;
您也可以使用Row_Number()
解决方案,但我倾向于偏离它,因为它通常与CROSS APPLY
TOP
的效果一样好。
SELECT
T.ID,
HT.TestID,
HT.Price
FROM
dbo.Test T
LEFT JOIN (
SELECT
Selector = Row_Number() OVER (
PARTITION BY HT.TestID ORDER BY HT.ID DESC
),
*
FROM dbo.TestHistory HT
) HT
ON T.ID = HT.TestID
AND HT.Selector = 1
;
Try this out yourself in a SQL Fiddle
找出TOP 1
或Row_Number()
解决方案是否表现更好的唯一方法是尝试使用大量具有正确代表性的数据来尝试数据库中的每个解决方案。如果您的历史记录条目和主要参赛作品很少,那么可能可以使用Row_Number()
获得更好的结果。但是,如果每个主条目都有许多历史条目,TOP
方法可能表现最佳。
表上的索引也会产生巨大的差异。确保您拥有允许正确访问表的合理索引(例如,表TestHistory
上的聚簇索引应该在TestID, ID
上,即使PK在ID
上也是如此)。如果每次都查询整个表,那么索引可能并不重要,但是当你有一个限制Test
行的条件时,索引将变得非常重要。