[英]tsql: alternative to select subquery in join
这是我简化的表格布局:
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的每一行上执行子查询。是否有办法提高此性能,还是以另一种方式呢?
使用下面的代码,并请注意,我按Date 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)
您可以在这些行中尝试一些操作,使用子查询根据日期字段获取最新信息(按pID分组),然后将其与第一个表连接,这样就不必不必对每一行都执行子查询表1的结果,将获得更好的性能:
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子句中。 希望这可以帮助。
使用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中为date列建立索引以提高性能(理想情况下,该索引还应覆盖table2的PrimaryID)
我在类似的scenaro中使用以下代码(我将其转录为您的示例)
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的
您可以使用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;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.