SQL MIN()&GROUP BYとエクストラフィールド
-
05-09-2019 - |
質問
GROUP BYと共に、SQL MIN()関数を使用する場合は、任意の追加の列(不MIN列、または列BY GROUPのいずれか)と一致MIN行のデータと一致します
たとえば、部門名、従業員名、および給与表を与えます:
SELECT MIN(e.salary), e.* FROM employee e GROUP BY department
もちろん、私は2つの良い列、最低賃金や部門を取得します。従業員名(および他の従業員のフィールド)が同じ行からでしょうか?すなわちMIN(給与)と行?
私は非常に、おそらく同じ(最低)給料で二人の従業員があるかもしれません知っているが、すべてが、私は(今)に関するすべての情報を取得していると心配です(または、のシングルの)最も安い従業員ます。
これは最も安いセールスマンを選択しますか?
SELECT min(salary), e.* FROM employee e WHERE department = 'sales'
基本的に、私はデータがMIN()関数と一緒に戻っていることを確認することができますその最小値を持つ(またはのシングルの)レコードにマッチする?
データベースの問題ならば、私はMySQLで働いています。
解決
あなたは私の頭の上から2つの選択肢があります。
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
2番目のステートメントは効果的に私にあなたが下の給与と同じ部署に別の従業員を見つけることができないすべての従業員を示し、発言によって動作します。
両方のケースでは、2つ以上の従業員が最小と同等の給与を持っている場合は、それらの両方(すべて)を取得します。
他のヒント
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)
にインデックスを持つことは非常にすべての3つのクエリを改善します。
最速の解決策ます:
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 = 1(従業員からROW_COUNTとして給与ASC BY DEPARTMENT_IDのORDER BY(PARTITION上FIRST_NAME、給与、ROW_NUMBER()を選択))から給与;