繁体   English   中英

tsql:在联接中选择子查询的替代方法

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM