Question

En utilisant la fonction SQL MIN (), avec GROUP BY, aura des colonnes supplémentaires (non la colonne MIN, ou l'un des groupes de colonnes) correspondent aux données de la rangée correspondant à MIN?

Par exemple, donné une table avec les noms des ministères, les noms des employés et le salaire:

SELECT MIN(e.salary), e.* FROM employee e GROUP BY department

Il est évident que je vais obtenir deux bonnes colonnes, le salaire minimum et le ministère. Est-ce que le nom de l'employé (et tous les autres domaines des employés) être de la même ligne? A savoir la ligne avec le MIN (salaire)?

Je sais qu'il pourrait très probablement être deux employés avec le même (et le plus bas) salaire, mais tout ce que je suis préoccupé par (maintenant) est d'obtenir toutes les informations sur le (ou un ) employé moins cher.

Ne serait-ce choisir le moins cher vendeur?

SELECT min(salary), e.* FROM employee e WHERE department = 'sales'

Pour l'essentiel, puis-je être sûr que les données renvoyées avec la fonction MIN () correspond à la volonté (ou un ) record avec cette valeur minimale?

Si les questions de base de données, je travaille avec MySql.

Était-ce utile?

La solution

Si vous voulez obtenir l'employé « moins cher » dans chaque département que vous avez deux choix du haut de ma tête:

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

Ou vous pouvez utiliser:

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

La deuxième déclaration fonctionne en disant efficace, montrez-moi tous les employés où vous ne pouvez pas trouver un autre employé dans le même département avec un salaire inférieur.

Dans les deux cas, si deux ou plusieurs employés ont des salaires égaux qui sont le minimum que vous les obtiendrez les deux (tout).

Autres conseils

SELECT  e.*
FROM    employee e
WHERE   e.id =
        (
        SELECT  id
        FROM    employee ei
        WHERE   ei.department = 'sales'
        ORDER BY
                e.salary
        LIMIT 1
        )

Pour obtenir des valeurs pour chaque service, utilisez:

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
        )

Pour obtenir des valeurs que pour les départements qui ont des employés, utilisez:

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
        )

Bien sûr, avoir un indice sur (department, salary) améliorera considérablement les trois requêtes.

La solution la plus rapide:

SET @dep := '';
SELECT * FROM (
  SELECT * FROM `employee` ORDER BY `department`, `salary`
) AS t WHERE IF ( @dep = t.`department`, FALSE, ( @dep := t.`department` ) OR TRUE );

Une autre approche peut être d'utiliser les fonctions analytiques. Voici la requête en utilisant des fonctions d'analyse et de no_lig

select first_name, de traitement (select first_name, salaire, ROW_NUMBER () plus (PARTITION PAR COMMANDE PAR DEPARTMENT_ID traitement ASC) en tant row_count des employés) où row_count = 1;

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top