这是我简化的表格布局:
table1:pID(pkey),数据 table2:rowID(pkey),pID(fkey),数据,日期
我想从table1中选择一些行,每个pID从table2连接一行,以获取该pID的最新日期。 我目前使用以下查询执行此操作:
SELECT * FROM table1 as a
LEFT JOIN table2 AS b ON b.rowID = (SELECT TOP(1) rowID FROM table2 WHERE pID = a.pID ORDER BY date DESC)
这种工作方式很慢,可能是因为它必须在表1的每一行上做一个子查询。有没有办法改善这方面的性能或以另一种方式做?
答案 0 :(得分:0)
使用下面的代码,并注意我按日期desc添加了订单以获取最新的数据
select *
from table1 a
inner join table2 b on a.pID=b.pID
where b.rowID in(select top(1) from table2 t where t.pID=a.pID order by Date desc)
答案 1 :(得分:0)
你可以在这些行上尝试一些东西,使用子查询根据日期字段获取最新信息(按pID分组),然后将其与第一个表连接,这样就不必执行子查询对于 Table1的每个行,将产生更好的性能:
Select *
FROM Table1 a
INNER JOIN
(
SELECT pID, Max(Date) FROM Table2
GROUP BY pID
) b
ON a.pID = b.pID
我使用 group by 为一列提供了示例SQL,如果您需要其他列,请将它们添加到GROUP BY子句中。希望这会有所帮助。
答案 2 :(得分:0)
使用ROW_NUMBER()函数获取一个列,说明表2中每行的哪个id是第一个(由pID分区,并由rowDate降序排序)
示例:
WITH cte AS
(
SELECT
rowID AS t2RowId,
ROW_NUMBER OVER (PARTITION BY pID ORDER BY rowDate DESC) AS rowNum
FROM table2 t2
) -- gets the t2RowIds + a column which says which is the latest for each pID
SELECT t1.*, t2.*
FROM table1 t1
LEFT JOIN
(
table2 t2
JOIN cte ON t2.rowID = cte.t2RowId AND cte.rowNum = 1
) ON t1.pID = t2.pID
这保证每个pID只返回table2中的1个项目,即使多个项目具有相同的日期。您当然应该确保在表2中索引日期列以获得快速性能(理想情况下,该索引也涵盖了table2的PrimaryID)
答案 3 :(得分:0)
我在类似的情感中使用下面的代码(我将其转录为您的示例)
SELECT b.*
FROM table1 AS a
left outer join (
SELECT a.*
FROM table2 a
inner join (
SELECT a.pID, max(date) as date
FROM table2
WHERE date <= <max_date>
group by pID
) b ON a.pID = b.pID AND a.date = b.date
) b ON a.pID = b.pID
) b on a.pID = b.pID
这种方法的唯一问题是你必须确保日期不会为pID重新定位
答案 4 :(得分:0)
您可以使用row_number()
函数和子查询执行此操作:
SELECT t1.*
FROM table1 t1 LEFT JOIN
(select t2.*, row_number() over (partition by pId order by rowId desc) as seqnum
from table2 t2
) t2
on t1.pId = t2.pId and t2.seqnum = 1;