sql — отображение оценок для зарплат между lowsal и hisal, а не между lowsal и hisal

#sql #join

#sql #Присоединиться

Вопрос:

Недавно я столкнулся с этим типом запроса..

У меня есть две таблицы

EMP

Эмпно Укажите зарплату отдела 
7012 Smith 10 1200 
7013 Allen 20 2100 
7014 Адамс 30 4000 
7015 Miller 20 4700 

Salgrade

Оценка Lowsal Hisal 
1 700 1201 
2 1500 2000 
3 2200 4001 
4 4600 5000 

Если зарплата сотрудника в emp находится между lowsal и hisal in salgrade , то должна отображаться соответствующая оценка, а если зарплата сотрудника не находится между lowsal и hisal , то должна отображаться предыдущая или последующая оценка.

Иллюстрация с примером

В таблицах примеров….

здесь для зарплаты сотрудника = 2100, что не находится между 1500 и 2000, тогда необходимо отобразить следующую оценку ‘3’. и для сотрудников зарплата = 4500, которая не находится между 4600 и 5000, тогда должна отображаться предшествующая оценка ‘3’.

Комментарии:

1. Какую СУБД вы используете? Postgres? Oracle?

2. При такого рода вопросах пример вывода — лучший способ показать, чего вы хотите. Кроме того, построение результатов вручную иногда может помочь вам определить, каким должен быть ваш запрос.

Ответ №1:

Попробуйте:

 select emp.*, salgrade.grade
  from emp
  left join salgrade
    on emp.salary between salgrade.lowsal and salgrade.hisal
  

Пример демонстрации:http://sqlfiddle.com /#!2 /df417 / 3 / 0

Обратите внимание, что я использовал внешнее объединение, потому что одна зарплата в вашем примере набора данных (employee # 7013) не входит в диапазон какой-либо оценки, поэтому он не показывает оценку.

Ответ №2:

Вы можете использовать AND с вашими JOIN s для создания более конкретных объединений.

 SELECT * 
  FROM emp 
  JOIN salgrade ON salary > salgrade.lowsal AND salary < salgrade.hisal
  

Однако Salgrade таблица не выглядит полной: сотрудники с зарплатой от 1202 до 1499 будут иметь grade = NULL

Ответ №3:

В MSSQL будет работать следующий запрос

 Select E.*, CASE WHEN grade IS NULL THEN 1 ELSE Grade END as Grade
from Emp E 
Left OUTER JOIN 
(
    select S.grade, S.lowSal, S.hiSal, G.hiSal as preLowSal 
    from salGrade S 
    LEFT OUTER JOIN salGrade G ON S.Grade = (G.Grade   1)
) SalG 
ON (salary >= lowsal and salary <= hiSal ) OR (salary >= preLowSal and salary <= lowSal)
  

Скрипка :http://sqlfiddle.com /#!2 /df417 /11