Extra-Felder mit SQL MIN() & GRUPPE DURCH
-
05-09-2019 - |
Frage
Bei der Verwendung von der SQL MIN () - Funktion zusammen mit der GRUPPE DURCH, wird jede weitere Spalten (nicht die MIN-Spalte oder eine GRUPPE VON Spalten) entsprechen den Daten in der entsprechenden Zeile MIN?
Beispielsweise, gegeben eine Tabelle mit-Abteilung-Namen, Namen der Mitarbeiter und Gehalt:
SELECT MIN(e.salary), e.* FROM employee e GROUP BY department
Natürlich werde ich bekommen zwei gut Spalten, den Mindestlohn und die Abteilung.Wird der name des Mitarbeiters (und alle anderen Arbeitnehmer Felder) werden aus der gleichen Reihe?Nämlich die Zeile mit der MIN(Gehalt)?
Ich weiß, es könnte sehr wahrscheinlich werden zwei Mitarbeiter mit den gleichen (und niedrigsten) Gehalt, aber ich bin besorgt, mit (jetzt) ist, immer alle Informationen auf dem (oder eine einzelne) günstigsten Mitarbeiter.
Würde diese wählen Sie den günstigsten Verkäufer?
SELECT min(salary), e.* FROM employee e WHERE department = 'sales'
Im wesentlichen kann ich sicher sein, dass die Daten zurückgegeben, die zusammen mit der MIN () - Funktion entspricht der (oder eine einzelne)- Eintrag mit, dass minimale Wert?
Wenn die Datenbank Fragen, ich arbeite mit MySql.
Lösung
Wenn Sie wollte, um die "billigste" der Mitarbeiter in jeder Abteilung würden Sie haben zwei Möglichkeiten aus der Spitze von meinem Kopf:
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
Oder Sie verwenden können:
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
Die zweite Anweisung arbeitet, effektiv zu sagen, zeige mir alle Mitarbeiter dort, wo Sie nicht finden können, ein weiterer Mitarbeiter in der gleichen Abteilung mit einem niedrigeren Gehalt.
In beiden Fällen, wenn zwei oder mehr Mitarbeiter haben gleiche Gehälter für die minimalen Sie Holen beide (alle).
Andere Tipps
SELECT e.*
FROM employee e
WHERE e.id =
(
SELECT id
FROM employee ei
WHERE ei.department = 'sales'
ORDER BY
e.salary
LIMIT 1
)
Um Werte für jede Abteilung, verwenden Sie:
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
)
Um die Werte für diese Abteilungen, die Mitarbeiter haben, verwenden Sie:
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
)
Natürlich, mit einem index auf (department, salary)
wird erheblich verbessern die alle drei Abfragen.
Die Schnellste Lösung:
SET @dep := '';
SELECT * FROM (
SELECT * FROM `employee` ORDER BY `department`, `salary`
) AS t WHERE IF ( @dep = t.`department`, FALSE, ( @dep := t.`department` ) OR TRUE );
Ein weiterer Ansatz kann sein, über Analytische Funktionen.Hier ist die Abfrage mit analytischen und ZEILE-Funktionen
select first_name, salary from (select first_name,Gehalt, Row_NUMBER() over (PARTITION BY DEPARTMENT_ID ORDER BY salary ASC) as row_count from employees), wo row_count=1;