SQL MIN() 및 GROUP BY를 사용한 추가 필드
-
05-09-2019 - |
문제
GROUP BY와 함께 SQL MIN() 함수를 사용할 때 추가 열(MIN 열이 아니거나 GROUP BY 열 중 하나)이 일치하는 MIN 행의 데이터와 일치합니까?
예를 들어, 부서 이름, 직원 이름, 급여가 포함된 테이블이 있습니다.
SELECT MIN(e.salary), e.* FROM employee e GROUP BY department
분명히 나는 최저 급여와 부서라는 두 개의 좋은 열을 얻게 될 것입니다.직원 이름(및 기타 직원 필드)이 동일한 행에 속합니까?즉, MIN(salary)이 있는 행?
나는 동일한(그리고 가장 낮은) 급여를 받는 두 명의 직원이 있을 수 있다는 것을 알고 있지만, (지금) 내가 관심을 갖는 것은 싱글) 가장 저렴한 직원.
가장 저렴한 세일즈맨을 선택하시겠습니까?
SELECT min(salary), e.* FROM employee e WHERE department = 'sales'
기본적으로 MIN() 함수와 함께 반환된 데이터가 (또는 싱글) 그 최소값으로 기록합니까?
데이터베이스가 중요하다면 MySql을 사용하고 있습니다.
해결책
각 부서에서 "가장 저렴한" 직원을 구하고 싶다면 내 머릿속에는 두 가지 선택이 있을 것입니다.
SELECT
E.* -- Don't actually use *, list out all of your columns
FROM
Employees E
INNER JOIN
(
SELECT
department,
MIN(salary) AS min_salary
FROM
Employees
GROUP BY
department
) AS SQ ON
SQ.department = E.department AND
SQ.min_salary = E.salary
또는 다음을 사용할 수 있습니다.
SELECT
E.*
FROM
Employees E1
LEFT OUTER JOIN Employees E2 ON
E2.department = E1.department AND
E2.salary < E1.salary
WHERE
E2.employee_id IS NULL -- You can use any NOT NULL column here
두 번째 진술은 같은 부서에서 더 낮은 급여를 받는 다른 직원을 찾을 수 없는 모든 직원을 보여 달라는 의미로 작동합니다.
두 경우 모두, 두 명 이상의 직원이 최소 금액인 동일한 급여를 받는 경우 둘 다(모두) 받게 됩니다.
다른 팁
SELECT e.*
FROM employee e
WHERE e.id =
(
SELECT id
FROM employee ei
WHERE ei.department = 'sales'
ORDER BY
e.salary
LIMIT 1
)
각 부서의 값을 얻으려면 다음을 사용하십시오.
SELECT e.*
FROM department d
LEFT JOIN
employee e
ON e.id =
(
SELECT id
FROM employee ei
WHERE ei.department = d.id
ORDER BY
e.salary
LIMIT 1
)
직원이 있는 부서에 대해서만 값을 얻으려면 다음을 사용하십시오.
SELECT e.*
FROM (
SELECT DISTINCT eo.department
FROM employee eo
) d
JOIN
employee e
ON e.id =
(
SELECT id
FROM employee ei
WHERE ei.department = d.department
ORDER BY
e.salary
LIMIT 1
)
물론, 인덱스를 가지고 있는 것은 (department, salary)
세 가지 쿼리 모두 크게 향상됩니다.
가장 빠른 솔루션:
SET @dep := '';
SELECT * FROM (
SELECT * FROM `employee` ORDER BY `department`, `salary`
) AS t WHERE IF ( @dep = t.`department`, FALSE, ( @dep := t.`department` ) OR TRUE );
또 다른 접근 방식은 분석 기능을 사용하는 것입니다.다음은 분석 및 ROW_NUM 함수를 사용한 쿼리입니다.
first_name, 급여 선택(직원의 row_count로 (PARTITION BY DEPARTMENT_ID ORDER BY 급여 ASC)에 대한 first_name, 급여, Row_NUMBER() 선택) 여기서 row_count=1;