一种方法是按树生成表示害虫等级的列,然后将排名过的害虫表连接到以等级为连接条件的树表中。确保使用 ROW_NUMBER 而不是 RANK,因为平局会导致 RANK 中的数字重复(但不是 ROW_NUMBER),并确保使用 LEFT OUTER 连接,因此不会排除害虫较少的树。此外,我按 2 个条件排序,但在普通 ORDER BY 子句中有效的任何内容在这里都有效。
DECLARE @t TABLE (TreeID INT, TreeName VARCHAR(25));
DECLARE @p TABLE (PestID INT, TreeID INT, PestName VARCHAR(25));
INSERT INTO @t VALUES (1,'ash'),(2,'elm'),(3,'oak')
INSERT INTO @p VALUES (1,1,'ash borer'),(2,1,'tent catapilar'),(3,1,'black weevil'),(4,1,'brown weevil');
INSERT INTO @p VALUES (5,2,'elm thrip'),(6,2,'wooly adelgid');
INSERT INTO @p VALUES (7,3,'oak gall wasp'),(8,3,'asian longhorn beetle'),(9,3,'aphids');
WITH cteRankedPests as (
SELECT PestID, TreeID, PestName, ROW_NUMBER() OVER (PARTITION BY TreeID ORDER BY PestName,PestID) as PestRank
FROM @p
)
SELECT T.TreeID, T.TreeName
, P1.PestID as P1ID, P1.PestName as P1Name
, P2.PestID as P2ID, P2.PestName as P2Name
, P3.PestID as P3ID, P3.PestName as P3Name
FROM @t as T
LEFT OUTER JOIN cteRankedPests as P1 ON T.TreeID = P1.TreeID AND P1.PestRank = 1
LEFT OUTER JOIN cteRankedPests as P2 ON T.TreeID = P2.TreeID AND P2.PestRank = 2
LEFT OUTER JOIN cteRankedPests as P3 ON T.TreeID = P3.TreeID AND P3.PestRank = 3