Pergunta

Ao usar a função SQL MIN (), juntamente com GROUP BY, vai quaisquer colunas adicionais (não a coluna MIN, ou um do grupo por colunas) coincidir com os dados na correspondência MIN linha?

Por exemplo, dada uma tabela com nomes de departamento, nomes de funcionários e salário:

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

Obviamente Vou pegar duas boas colunas, do salário mínimo e do departamento. Será que o nome do funcionário (e quaisquer outros campos de funcionários) ser da mesma linha? Ou seja, a linha com o MIN (salário)?

Eu sei que há poderia muito possivelmente ser dois funcionários com o mesmo (e menor) salário, mas tudo que eu estou preocupado com a (agora) é obter todas as informações sobre o (ou um único ) empregado mais barato.

Será que essa escolha o vendedor mais barato?

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

Essencialmente, eu posso ter certeza de que os dados retornados juntamente com a função MIN () irá corresponder ao (ou a único) registro com que o valor mínimo?

Se as questões de banco de dados, eu estou trabalhando com o MySQL.

Foi útil?

Solução

Se você quiser obter o "mais barato" empregado em cada departamento, você teria duas opções em cima da minha cabeça:

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 você pode usar:

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

A segunda instrução funciona dizendo efetivamente, mostre-me todos os funcionários, onde você não pode encontrar um outro funcionário do mesmo departamento com um salário mais baixo.

Em ambos os casos, se dois ou mais funcionários têm salários iguais que são o mínimo que você vai buscá-los ambos (todos).

Outras dicas

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

Para obter valores para cada departamento, use:

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
        )

Para obter valores apenas para os departamentos que têm empregados, de uso:

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
        )

É claro que ter um índice em (department, salary) vai melhorar muito as três consultas.

A solução mais rápida:

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

Outra abordagem pode ser o uso de funções analíticas. Aqui está a consulta usando funções analíticas e núm_linha

seleccione primeiro_nome, salário de (primeiro_nome seleccione, salário, row_number () ao longo de (partição POR ORDEM DEPARTMENT_ID pela ASC salário) como row_count dos empregados) onde row_count = 1;

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top