SQL为每个父/子项系列选择一个日期范围

时间:2016-06-28 17:20:29

标签: sql join parent-child

我有一个为所有带有范围键的父/子类型项构建的层次结构(临时表)。我有一个表(LastOrdr),它具有所有项目的最后订单日期(无论父/子)。然后我有所有项目的主项目表。

我有一个查询,选择符合某个lastorderdate条件的所有非父/子项。它是一个简单的查询,它将主项目表与LastOrdr表连接起来,从提供的用户参数中获取max(lastorderdate)。

我的挑战是为父母/儿童产品做同样的事情。对于父/子项目(一个父母,最多可以有8个孩子,但在大多数情况下可以有2/3)。对于一个家庭来说,选择是必须将max(lastorderdate)应用于整个家庭。我的意思是,如果我有3个孩子为父母,我需要从LastOrdr.lastorderdate中找到此系列中所有4个(1个父项和3个孩子)项的最大值,然后将其与用户提供的参数进行比较。如果它符合一个家庭的标准,我想选择那个家庭,否则,丢弃它。

非常感谢实现这一目标的一些指导。

感谢。

表1(主要项目):

itemID    ParentID    Descrip    ......
21         2           .....
22         2           .....
23         2           .....
24         2           .....
27         3           .....
29         3           .....
33         3           .....
41         3           .....
......................

表2(LastOrdr):

ItemID    lastorderdate
2          2014-01-01
21         2014-07-21
21         2015-01-12
22         2013-01-01
23         2014-04-01
27         2013-01-23
...........................

2 个答案:

答案 0 :(得分:1)

你没有发布任何表结构,所以我只是给出我的一般方法。 首先,我将通过创建一个额外的列来识别分组,从而对父母和孩子进行分组。我会UNION父母和孩子,并附加列parentId

itemId | parentId
1      | 1
2      | 1
7      | 1
9      | 1
3      | 3
6      | 3

从这里开始,您可以GROUP BY parentId获取MAX(lastorderdate)。如果您发布表格结构,我可以更详细。

尝试以下查询:

SELECT *
FROM (
    SELECT a.ParentID, MAX(orderdate) AS 'LatestOrder'
    FROM table1 a
    JOIN Table2 b ON b.ItemID = a.ItemID
    GROUP BY ParentID
) c
JOIN table2 d ON d.OrderDate = c.LatestOrder
JOIN table1 e ON e.ItemId = d.ItemId AND e.ParentId = c.ParentID 

答案 1 :(得分:1)

以下查询返回您想要的内容。

declare @master table (itemID int, ParentID int)
insert @master values
(21         ,2 ),
( 22         ,2), 
( 23         ,2 ),
( 24         ,2 ),
( 27         ,3 ),
( 29         ,3 ),
( 33         ,3 ),
( 41         ,3),
(2, 2), --I added this data
(3, 2)  --
--,(44,21) --if you wish grandchild

declare @LastOrdr table(ItemID int, lastorderdate date)
insert @LastOrdr values
(2          ,'2014-01-01'),
(21         ,'2014-07-21'),
(21         ,'2015-01-12'),
(22         ,'2013-01-01'),
(23         ,'2014-04-01'),
(27         ,'2013-01-23')
--,(44, '2015-04-15') --grandchild's order

;with master as (--create recursive (hierarchical) CTE
--anchor query: items w/out parents
select itemid, itemid ParentID --fix value
from @master where ParentID = itemId --parent to itsellf
union all
--recursive query down the tree
select m.itemid, m1.ParentID
from @master m
inner join master m1 on m.ParentID=m1.itemID
)--end CTE
select m.ParentID, max( lo.lastorderdate) lastorderdate
from master m
inner join @LastOrdr lo on m.itemID=lo.ItemID --join by childId
where lo.lastorderdate< '2015-05-29' -- use ISO date
group by m.ParentID --group by parent