Alternatywa dla inner join

0

Witam.
Treść zadania brzmi następująco :
6. Wyświetl dla każdego pracownika jego nazwisko (last_name), numer oddziału (department_id) oraz nazwiska wszystkich
pracowników, którzy pracują razem z nim w tym samym oddziale. Nazwij odpowiednio każdą z kolumn.

Z użyciem inner join wygląda chyba tak :

SELECT e.last_name AS FIRSTNAME,e.department_id AS DEPARTMENT,ee.last_name AS COLLEAGUE
FROM (employees e INNER JOIN departments d ON e.department_id = d.department_id INNER JOIN employees ee ON (ee.department_id = e.department_id AND ee.employee_id != e.employee_id))
ORDER BY e.department_id ASC

Zaś jakby to wyglądało bez nich ? Bo niestety prowadzący uważa, że inner join jest zbyt mało pouczający i trzeba robić bez nich.
Ja zaś sam sobie nie mogę z tym poradzić.

SELECT e.last_name AS FIRSTNAME,e.department_id AS DEPARTMENT, (select ee.last_name from employees ee where e.employee_id != ee.employee_id) from employees e

schemat bazy jak i dane do bazy umieszczam w załączniku

Pozdrawiam

7
kenik napisał(a):

Zaś jakby to wyglądało bez nich ? Bo niestety prowadzący uważa, że inner join jest zbyt mało pouczający i trzeba robić bez nich.

Zmień prowadzącego, albo powiedz mu, by zmienił lekarstwa...

0

Skoro prowadzący to debil to zrób rozwiązanie dla debila:

SELECT e.last_name AS FIRSTNAME,e.department_id AS DEPARTMENT,ee.last_name AS COLLEAGUE
  FROM employees e, departments d, employees ee
 WHERE e.department_id = d.department_id  
   AND ee.department_id = e.department_id 
   AND ee.employee_id != e.employee_id
 ORDER BY e.department_id ASC
3

Zamień "INNER JOIN" na "JOIN"

0

albo na left join

SELECT
  e.last_name AS FIRSTNAME,
  e.department_id AS DEPARTMENT,
  ee.last_name AS COLLEAGUE
FROM 
  employees e 
  left JOIN departments d ON e.department_id = d.department_id 
  left JOIN employees ee ON ee.department_id = e.department_id AND ee.employee_id != e.employee_id
where
  d.department_id  is not null
  and ee.department_id is not null
ORDER BY e.department_id ASC
3

Zawsze możemy pośmiać się z prowadzącego, że inner joiny są mało pouczajace, można podejść kreatywnie do problemu i rozwiązać bez joina, wtedy naprawdę można się sporo nauczyć, wiec edukacyjny walor na pewno jest zachowany:

Dla SQL = 2017

select 
	last_name
	,(select STRING_AGG(last_name,',') from employees c where c.departament_id = e.departament_id and e.employee_id <> c.employee_id ) COLLEAGUE 
from 
	employees e

Dla SQL >=2005

select 
	last_name
	, STUFF((select 
				', ' + last_name 
			from 
				employees c 
			where 
				c.department_id = e.department_id 
				and e.employee_id <> c.employee_id 
			FOR XML PATH(''),TYPE).value('(./text())[1]','VARCHAR(MAX)')
		,1,2,'') COLLEAGUE
from 
	employees e

Rekurencja

with cteR as(
select
	1 N
	,employee_id
	,last_name
	,last_name COLLEAGUE
	,department_id
from 
	employees 
union all
select
	N+1
	,c.employee_id
	,c.last_name
	,cteR.last_name COLLEAGUE
	,c.department_id
from
	employees c
	inner join cteR on cteR.department_id = c.department_id and  cteR.employee_id <> c.employee_id
where
	cteR.N = 1
)

select last_name,COLLEAGUE,department_id  from cteR 
where n > 1
order by 1

Kursor:

DECLARE @results TABLE (
	employee_id    INT
	,last_name      VARCHAR(25)
	,department_id  INT
	,COLLEAGUE VARCHAR(25)
)
DECLARE @e as CURSOR;
DECLARE @eID as INTEGER 
declare @last_name as varchar(25)
declare @dID as integer
SET @e = CURSOR FORWARD_ONLY FOR
SELECT employee_id, last_name, department_id  FROM employees 

OPEN @e
FETCH NEXT FROM @e INTO @eID, @last_name, @dID;
WHILE @@FETCH_STATUS = 0
BEGIN
	insert into @results
	select 
		@eID
		,@last_name
		,department_id
		,last_name 
	from 
		employees c 
	where 
		c.department_id = @dID
		and employee_id<>@eID;

	FETCH NEXT FROM @e INTO @eID, @last_name, @dID;
END
close @e
deallocate @e

select 
	last_name
	,department_id
	, COLLEAGUE 
from 
	@results

Więc nie popieram szydery i heheszków z prowadzącego uważam to za rozwijające, tylko trzeba wyjść z poziomu myślenia o tym, że prowadzący jest głupi, a zastanawić się faktycznie nad rozwiązaniem. Sam pisałeś, ze celem "zabrania" joinów nie jest ich negacja... sam widzę jeszcze 3 rozwiązania nie uzywające joinów.

1 użytkowników online, w tym zalogowanych: 0, gości: 1