这在一个查询中可能无法实现,但我想知道我的选择是什么。
我有一个大型查询,它返回每个库存的数据(在本例中为树)。查询从几个不同的表中获取数据。我主要使用左外连接来提供这些信息,所以如果它不在那里我可以忽略它并取NULL。我有一个有趣的情况,“树”和它的“害虫”之间存在一对多的关系。
我需要一个查询来获取每棵树的前6个害虫并将它们作为列返回:
我知道我可以在多个查询中执行此操作,但是每次使用会发生数千次,而我们的服务器无法处理。
一些注意事项:我们使用的是ColdFusionMX7,而且我对存储过程的了解非常少。
答案 0 :(得分:1)
一种方法是通过树生成表示有害生物等级的列,然后将等级有害生物表连接到树表,其中等级作为连接条件。确保使用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