Начало » SQL.RU » Вопрос-Ответ » Помощь экспертов так сказать (Обучение ) 
	
		
		
			| Помощь экспертов так сказать [сообщение #4569] | 
			Mon, 04 March 2024 15:15   | 
		 
		
			
				
				
				
					
						  
						JustAlex
						 Сообщений: 5 Зарегистрирован: March 2024 
						
					 | 
					Junior Member  | 
					 | 
		 
		 
	 | 
 
	
		Доброго времени суток, форумчане! 
 
На данный момент нахожусь в процессе изучения SQL посредством платформы LearnDB.ru, застрял уже на 4-й задаче 3-го курса (кому не лень - лучше зайти и посмотреть, это бесплатно, вроде как можно перескакивать на курсы, не проходя предыдующие). Собственно, прошу помощи у уважаемых продвинутых пользователей. 
 
Условия задачи следующие: 
 
"Помоги сотрудникам найти повышение в должности, либо перейти на ту же должность, но в другой магазин. 
Для каждого сотрудника получи информацию о должностях либо магазина, в котором работает сотрудник, либо должностях с таким же индентификатором должности в другом магазине. 
 
Выведи следующие столбцы: 
last_name - фамилия сотрудника; 
first_name - имя сотрудника; 
store_id_employee - идентификатор магазина сотрудника; 
store_id_rank - идентификатор магазина должности; 
rank_id - идентификатор должности в магазине; 
rank_name - название должности. 
 
Отсортируй результат по 
фамилии; 
имени; 
идентификатору магазина должности; 
идентификатору должности". 
 
Таблицы, которые нужно использовать: employee (далее - e, прил. 1) и rank (далее - r, прил. 2). 
Схема данных также прилагается (прил. 3). 
 
Вот эталонное решение, которое предлагает сайт: 
 
SELECT e.last_name, 
       e.first_name, 
       e.store_id as store_id_employee, 
       r.store_id as store_id_rank, 
       r.rank_id, 
       r.name as rank_name 
  FROM employee e 
  JOIN rank r 
    ON r.store_id = e.store_id 
    OR (r.rank_id = e.rank_id AND r.store_id != e.store_id) 
 ORDER BY e.last_name, e.first_name, r.store_id, r.rank_id 
 
Вот мое решение, которое сработало (как - я не понимаю, нашел, по сути, методом "тыка"): 
 
SELECT e.last_name, 
       e.first_name, 
       e.store_id AS store_id_employee, 
       r.store_id AS store_id_rank, 
       r.rank_id, 
       r.name AS rank_name 
  FROM employee e 
  JOIN rank r 
    ON r.rank_id = e.rank_id 
   AND r.store_id != e.store_id 
    OR r.store_id = e.store_id 
ORDER BY e.last_name, e.first_name, r.store_id, r.rank_id 
 
Я не понимаю, почему оператор ON, - а точнее то, что идет после него, - выглядит именно так, как оно выглядит в решениях. 
 
Вопрос 1 
Как видно на схеме данных (прил. 3), таблице r присвоено два ключа: store_id и rank_id. Соответственно, чтобы name (название должности) из таблицы r привязалось к конкретному employee_id (идентификатор сотрудника) из таблицы e, нужно, чтобы store_id и rank_id из таблицы r привязались к store_id и rank_id из таблицы e, то есть решение, по моей логике, в любом случае должно содержать следующее в качестве не достаточного, но необходимого условия: 
 
  FROM employee e 
  JOIN rank r 
    ON r.store_id = e.store_id 
    AND r.rank_id = e.rank_id 
    ... 
 
Однако, как мы видим в эталонном решении, этого нет, вместо этого: 
 
 FROM employee e 
  JOIN rank r 
    ON r.store_id = e.store_id 
    OR (r.rank_id = e.rank_id AND r.store_id != e.store_id) 
 
То есть в эталонном решении, как я понимаю, в обязательном порядке из r к e присоединяется только store_id. Как в таком случае name (название должности) из r будет верно для employee_id из e, если для определения name из r используются два ключа store_id и rank_id, а не только store_id? 
 
 
Вопрос 2 
Почему такой вариант решения работает: 
 
SELECT e.last_name, 
       e.first_name, 
       e.store_id AS store_id_employee, 
       r.store_id AS store_id_rank, 
       r.rank_id, 
       r.name AS rank_name 
  FROM employee e 
  JOIN rank r 
    ON r.rank_id = e.rank_id 
   AND r.store_id != e.store_id 
    OR r.store_id = e.store_id 
ORDER BY e.last_name, e.first_name, r.store_id, r.rank_id 
 
а такой нет (оставил только отличающуюся часть): 
 
    ON r.rank_id = e.rank_id 
   AND r.store_id = e.store_id 
    OR r.store_id != e.store_id 
 
Чем они отличаются? Какая разница в каком порядке стоит то, что между OR? "Купи арбуз или дыню" и "купи дыню или арбуз" это одно и то же - что я не понимаю? 
 
Прошу прощения за много букв. Был бы очень благодарен за помощь.
		
		
		
 |  
	| 
		
	 | 
 
 
 |  
	| 
		
 |  
	| 
		
 |  
	| 
		
 |  
	| 
		
 |  
	
		
		
			| Re: Помощь экспертов так сказать [сообщение #4575 является ответом на сообщение #4573] | 
			Wed, 06 March 2024 11:09    | 
		 
		
			
				
				
				
					
						  
						JustAlex
						 Сообщений: 5 Зарегистрирован: March 2024 
						
					 | 
					Junior Member  | 
					 | 
		 
		 
	 | 
 
	
		Так прочитал и все равно не понял. Приоритет следуюдий - 1) NOT, 2) AND и 3) OR. 
Соответственно, как я понимаю, в этом выражении 
 
r.rank_id = e.rank_id 
  AND r.store_id != e.store_id 
   OR r.store_id = e.store_id 
 
будут выдаваться результаты, в которых для e из r совпадает rank_id и store_id или совпадает rank_id и не совпадает store_id. 
 
Если это верно, то почему в этом выражении 
 
r.rank_id = e.rank_id 
  AND r.store_id = e.store_id 
   OR r.store_id != e.store_id 
 
не будет того же самого, если разница только в том, что то, что между OR, поменяли местами? 
 
Условно, как я писал выше, выражение "купи бутерброд с колбасой или сыром" и выражение "купи бутерброд с сыром или колбасой" равнозначны. Почему здесь так не работает? 
  
		
		
		[Обновления: Wed, 06 March 2024 11:11] Известить модератора  
 |  
	| 
		
	 | 
 
 
 |  
	| 
		
 |  
	| 
		
 |  
	
		
		
			| Re: Помощь экспертов так сказать [сообщение #4578 является ответом на сообщение #4577] | 
			Wed, 06 March 2024 14:01    | 
		 
		
			
				
				
				
					
						  
						JustAlex
						 Сообщений: 5 Зарегистрирован: March 2024 
						
					 | 
					Junior Member  | 
					 | 
		 
		 
	 | 
 
	
		Для первого: 
r.rank_id = e.rank_id AND r.store_id != e.store_id OR r.store_id = e.store_id 
 
будет выглядеть следующим образом: 
1) r.rank_id = e.rank_id + r.store_id != e.store_id 
2) r.rank_id = e.rank_id + r.store_id = e.store_id 
 
Если со скобками, то можно, наверное, так представить: 
(r.rank_id = e.rank_id AND r.store_id != e.store_id) 
OR (r.rank_id = e.rank_id AND r.store_id = e.store_id  
 
Для второго: 
r.rank_id = e.rank_id AND r.store_id = e.store_id  OR r.store_id != e.store_id 
 
будет выглядеть следующим образом: 
1) r.rank_id = e.rank_id + r.store_id = e.store_id 
2) r.rank_id = e.rank_id + r.store_id != e.store_id 
 
Я так это вижу. Но раз Вы говорите, что это неправильно, я верю. Пытаюсь лишь понять, почему это неправильно и какой порядок.
		
		
		[Обновления: Wed, 06 March 2024 14:03] Известить модератора  
 |  
	| 
		
	 | 
 
 
 |  
	| 
		
 |  
	
		
		
			| Re: Помощь экспертов так сказать [сообщение #4581 является ответом на сообщение #4580] | 
			Wed, 06 March 2024 17:39   | 
		 
		
			
				
				
				
					
						  
						JustAlex
						 Сообщений: 5 Зарегистрирован: March 2024 
						
					 | 
					Junior Member  | 
					 | 
		 
		 
	 | 
 
	
		1) (x * y) + z 
 
2) (a AND b) OR c 
 
3) Честно говоря, я не знал, что можно совмещать операторы таким образом  - OR NOT, но полагаю, что a AND b OR NOT b можно представить так: (NOT b) OR (a AND b) 
 
PS Такое бывает, когда занимаешься чем-то всего четыре дня) Благодарю Вас за помощь
		
		
		
 |  
	| 
		
	 | 
 
 
 |   
Переход к форуму:
 
 Текущее время: Tue Nov 04 03:59:17 GMT+3 2025 
 Общее время, затраченное на создание страницы: 0.01326 секунд 
 |