分拣主子

时间:2019-12-24 13:21:38

标签: sql sql-server

以下是表格:

    Groups      Method  RDate
1   master_6    Sales   2019-10-17
2   master_3    ITO     2017-12-22
3   child_6     SRT     2019-10-21
4   master_4    TO      2019-02-07
5   child_3     ITI     2019-03-09
6   child_6     SRT     2019-03-14
7   master_6    Sales   2019-03-14
8   child_4     TR      2019-03-14
9   master_6    Sales   2019-03-14

我想要输出如下。

    Groups      Method  RDate
2   master_3    ITO     2017-12-22
5   child_3     ITI     2019-03-09
4   master_4    TO      2019-02-07
8   child_4     TR      2019-03-14
7   master_6    Sales   2019-03-14
6   child_6     SRT     2019-03-14
9   master_6    Sales   2019-03-14
3   child_6     SRT     2019-10-21
1   master_6    Sales   2019-10-17

逻辑是:

采用所有包含单词“ master”的行,并按日期对其进行排序。

结果,第一行应为具有最旧日期的Master,

下一行应为该主机的子机(master_1的孩子为Child_1,master_2的孩子_2,依此类推)

然后选择下一个主文件(倒数第二个最低日期),然后选择其子对象

例如 日期最低的master是rec#2,因此它将排在第一行。然后对于第二行,找到该master_3的子对象,因此将其为child_3(如果发现child_3的记录多于1条,则考虑最低日期并将其放在结果的第二行中),然后是下一个主记录,依此类推。 / p> 希望我能很好地解释一切。

drop table if exists #A

CREATE TABLE #A(Groups varchar(15), Method varchar(15), RDate date)
insert into #A values

('master_6','Sales','2019/10/17'),
('master_3','ITO','2017/12/22'),
('child_6','SRT','2019/10/21'),
('master_4','TO','2019/02/07'),
('child_3','ITI','2019/03/09'),
('child_6','SRT','2019/03/14'),
('master_6','Sales','2019/03/14'),
('child_4','TR','2019/03/14'),
('master_6','Sales','2019/03/14');

由于存在一些混乱,我试图用另一种方式解释:

在我的情况下,任何一位主人(父母)将只有一种类型的孩子,但可以有同一个孩子的多个记录,为了说明一下,假设ParentA一年访问剧院6次,而ChildA访问了5次。 ParentB拜访了3次,他们的孩子拜访了3次。所有这些记录均按日期存储在一个表中,但不按任何顺序存储。

我想输出在后台将所有父母及其日期按升序排列的输出,然后从该背景列表中选择第一位父母,找到孩子的来访-如果发现很多访问,则只进行孩子的第一次访问,因为他的父母访问了也是第一位。

然后从父级列表中获取第二条记录,并找到他们的孩子的来访 如果这是同一位父母的第二次访问,则找到孩子的第二次访问;如果未找到任何东西,则转到父级列表的第三行,找到它的孩子的访问。

所有剩余的父母或孩子的探访将在结束列表中。

2 个答案:

答案 0 :(得分:2)

对于示例数据,您可以在order by中进行:

order by max(case when groups like 'master%' then date end) over (partition by right(groups, 1)) asc,
         right(groups, 1),
         (case when groups like 'master%' then 1 else 2 end)

这是在做

  • 根据组的“主”日期计算整个组的日期。
  • 将所有组保持在一起,以防发生联系。
  • 将主记录放在孩子之前。

答案 1 :(得分:1)

主人将孩子的号码给孩子时,他们可以在一起。

with CTE_MASTERS as
(
  select Groups, Method, Rdate
  , substring(Groups,patindex('%[_]%',Groups)+1,len(Groups)) as groupNr
  , row_number() over (partition by Groups order by rdate) as groupRownum
  , row_number() over (order by rdate, Groups) as masterRownum
  from #A
  where Groups like 'master%'
)
, CTE_CHILDS as
(
  select Groups, Method, Rdate
  , substring(Groups,patindex('%[_]%',Groups)+1,len(Groups)) as groupNr
  , row_number() over (partition by Groups order by rdate) as groupRownum
  from #A
  where Groups like 'child%'
)
, CTE_MASTERS_AND_CHILDS as
(
  select *
  , cast(1 as bit) as isMaster
  from CTE_MASTERS

  UNION ALL

  select c.*
  , m.masterRownum
  , 0
  from CTE_CHILDS c
  left join CTE_MASTERS m
    on c.groupNr = m.groupNr 
  and c.groupRownum = m.groupRownum
)
SELECT Groups, Method, Rdate
FROM CTE_MASTERS_AND_CHILDS
ORDER BY 
masterRownum,
isMaster desc,
groupNr,
groupRownum;
Groups   | Method | Rdate              
:------- | :----- | :------------------
master_3 | ITO    | 22/12/2017 00:00:00
child_3  | ITI    | 09/03/2019 00:00:00
master_4 | TO     | 07/02/2019 00:00:00
child_4  | TR     | 14/03/2019 00:00:00
master_6 | Sales  | 14/03/2019 00:00:00
child_6  | SRT    | 14/03/2019 00:00:00
master_6 | Sales  | 14/03/2019 00:00:00
child_6  | SRT    | 21/10/2019 00:00:00
master_6 | Sales  | 17/10/2019 00:00:00

db <>提琴here