我正在尝试找出以下解决方案,我需要找到对员工>经理并打印出来。
给定的表是:
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
现在,我需要得到如下结果,例如:
见下文:
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
答案 0 :(得分:1)
我假设你的样本数据存在缺陷: 我不希望看到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;所以这里也定义了扩展模式。