Я пытаюсь найти решение для следующего: мне нужно найти пары employee> manager и распечатать его.
Данная таблица:
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
Я предполагаю, что ваши образцы данных испорчены: я не ожидал увидеть, что Дьюайн Биггс и Захария Йочум в паре с самим собой.
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()
чтобы ограничить данные в первом столбце, чтобы содержать только номера нечетных строк, которые мы оставили внешними, присоединяем это ко второму набору данных, содержащим даже номера строк для каждого менеджера, и включаем только те записи, которые сопоставляются с менеджером, и когда номер строки 1 больше, таким образом, четное число, если оно существует. Эта логика видна в демоверсии, так как я включал поля RN как для производной таблицы 1, так и для производной таблицы 2. Каждая производная таблица (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- mod(der_tab_col1.rn,2)
предложения mod(der_tab_col1.rn,2)
просто означает разделение RN (номер строки) на 2, если есть остаток, тогда он нечетный, и мы хотим их. Если это даже тогда мы не хотим, поскольку четные строки будут в столбце 2.
Используя этот подход, можно увидеть мощность аналитических функций даже в симулированных средствах.
Примечание: мы могли бы продолжить концепцию левых объединений и пользовательских переменных и использовать mod 3 вместо 2, если нам нужно 3 парных имени вместо 2; поэтому здесь также определен шаблон расширения.
ID
столбца? На каком основании вы решаете, если два сотрудника в паре и кто остается один, если менеджер управляет 3 человека? В случае двух человек, кто является спаренным1 против спаренным2?