在两列表中查找对并加入三列表

时间:2018-02-19 21:22:41

标签: mysql sorting join group-by

我正在尝试找出以下解决方案,我需要找到对员工>经理并打印出来。

给定的表是:

employee            manager
----------------------------------
Bryce Posada        Antony Real  
Sung Hosey          Aurelio Havlik  
Joan Strother       Aurelio Havlik  
Irwin Fulks         Barton Rose  
Rocco Keplin        Benito Cowboy  
Efrain Ricketson    Benito Cowboy  
Patricia Hackenberg Benito Cowboy  
Paris Sigala        Chuck Lawson  
Alva Kaul           Ernest Divens  
Eli Bielecki        Ernest Divens  
Walton Virden       Ernest Divens  
Raphael Montesino   Ernest Divens  
Dewayne Biggs       Lonny Meller  
Josef Bakken        Marc Margulies  
Everett Gresham     Marc Margulies  
Zachariah Yochum    Otto Brannum  

现在,我需要得到如下结果,例如:

  • 安东尼皇家只管理一个人,所以会有一个空的 对
  • Aurelio Havlik管理两个人,所以会有一对。
  • Benito Cowboy管理着三个人,所以会有一对一 记录为null。

见下文:

employee_paired1        employee_paired2    manager
---------------------------------------------------------
Bryce Posada            null                Antony Real  
Sung Hosey              Joan Strother       Aurelio Havlik  
Irwin Fulks             null                Barton Rose  
Rocco Keplin            Efrain Ricketson    Benito Cowboy  
Patricia Hackenberg     null                Benito Cowboy  
Paris Sigala            null                Chuck Lawson  
Alva Kaul               Eli Bielecki        Ernest Divens  
Walton Virden           Raphael Montesino   Ernest Divens  
Dewayne Biggs           Dewayne Biggs       Lonny Meller  
Josef Bakken            Everett Gresham     Marc Margulies  
Zachariah Yochum        Zachariah Yochum    Otto Brannum  

到目前为止,我的代码生成了结果,但它们重叠......

修改:根据要求,我正在添加SQL Fiddle

示例代码符合本论坛的规则:

select * from ( 
select max(c1.employee) employee1, c2.employee employee2, c1.manager creator from test3 c1
join test3 c2 on c1.manager = c2.manager
and c1.employee < c2.employee
) a

1 个答案:

答案 0 :(得分:1)

Demo on Rextester

我假设你的样本数据存在缺陷: 我不希望看到Dewayne Biggs和Zachariah Yochum与他们配对。

employee_paired1        employee_paired2    manager
---------------------------------------------------------
Dewayne Biggs           Dewayne Biggs       Lonny Meller  
Zachariah Yochum        Zachariah Yochum    Otto Brannum  

我还假设配对的顺序,谁在第1对,谁不重要。所以我使用了简单地按员工列排序的方法,因此按字母顺序排列的名字将始终是奇怪的人,而具有最早字母名称的名称将始终是第1名中的第一名。

有点棘手......但是使用用户变量(@MGR,下面的@RN)来模拟row_number功能,包括数据分区;和函数mod()我们可以生成两组数据,一组用于第一列Der_tab_col1,另一组用于第二列。我们使用Mod()来限制第一列中的数据仅包含我们将外部连接的奇数行号连接到包含每个管理器的偶数行数的第二组数据,并且仅包括那些在管理器上匹配的记录以及何时行number为1,因此如果存在则为偶数。这个逻辑在演示中可见,因为我包括派生表1和派生表2的RN字段。每个派生表(der_tab_Col1,Der_tab_col2)对相同的基础数据集使用相同的顺序并执行,确保我们获得每个查询中的顺序和结果相同)。

SELECT Der_tab_Col1.employee as employee_paired1        
     , Der_tab_Col2.employee as employee_paired2    
     , Der_tab_Col1.manager
FROM (SELECT A.Employee
           , case when @MGR <> A.Manager THEN @RN:=0 end as resetRN
           , @RN:=@RN+1  RN
           , @MGR:=A.Manager as Manager
      FROM SO48874377 A
      CROSS JOIN (Select @RN:=0, @MGR:='') Z
      ORDER BY manager, employee) Der_tab_Col1
LEFT JOIN (SELECT A.Employee
                , case when @MGR2 <> A.Manager THEN @RN2:=0 end as resetRN
                , @RN2:=@RN2+1  RN
                , @MGR2:=A.Manager as Manager
      FROM SO48874377 A
      CROSS JOIN (Select @RN2:=0, @MGR2:='') Z
      ORDER BY manager, employee) Der_Tab_col2
   on Der_tab_Col1.Manager = Der_tab_Col2.Manager
  and Der_tab_Col1.RN+1 = Der_tab_Col2.RN
WHERE mod(der_tab_col1.rn,2)=1
ORDER BY der_tab_col1.manager, Der_tab_Col1.RN;

给我们:

+----+-------------------+---------------------+----------------+
|    | employee_paired1  | employee_paired2    |    manager     |
+----+-------------------+---------------------+----------------+
|  1 | Bryce Posada      | NULL                | Antony Real    |
|  2 | Joan Strother     | Sung Hosey          | Aurelio Havlik |
|  3 | Irwin Fulks       | NULL                | Barton Rose    |
|  4 | Efrain Ricketson  | Patricia Hackenberg | Benito Cowboy  |
|  5 | Rocco Keplin      | NULL                | Benito Cowboy  |
|  6 | Paris Sigala      | NULL                | Chuck Lawson   |
|  7 | Alva Kaul         | Eli Bielecki        | Ernest Divens  |
|  8 | Raphael Montesino | Walton Virden       | Ernest Divens  |
|  9 | Dewayne Biggs     | NULL                | Lonny Meller   |
| 10 | Everett Gresham   | Josef Bakken        | Marc Margulies |
| 11 | Zachariah Yochum  | NULL                | Otto Brannum   |
+----+-------------------+---------------------+----------------+

SQL where子句mod(der_tab_col1.rn,2)只是意味着将RN(行号)除以2,如果有余数则为奇数,我们想要那些。如果它甚至那么我们就不会想要那些,因为偶数行将在第2列。

即使在使用这种方法的模拟方法中,也可以看到分析函数的强大功能。

注意:如果我们想要3个配对名称而不是2个,我们可以继续左连接和用户变量的概念并使用mod 3而不是2;所以这里也定义了扩展模式。