SQL: Grupo mínimo valor en un campo, mientras que la selección de filas distintas

Aquí es lo que estoy tratando de hacer. Digamos que tengo esta tabla t:

id | record_date | other_cols
18 | 2011-04-03  | x
18 | 2012-05-19  | y
18 | 2012-08-09  | z
19 | 2009-06-01  | a
19 | 2011-04-03  | b
19 | 2011-10-25  | c
19 | 2012-08-09  | d

Para cada id, quiero seleccione la fila que contiene el mínimo record_date. Así que me gustaría conseguir:

id | record_date | other_cols
18 | 2011-04-03  | x
19 | 2009-06-01  | a

La única solución que he visto para este problema suponga que todos los record_date entradas son distintas, pero que no es este caso en mis datos. El uso de una subconsulta y un inner join con dos condiciones me daría filas duplicadas para algunos identificadores, que no quiero:

id | record_date | other_cols
18 | 2011-04-03  | x
19 | 2011-04-03  | b
19 | 2009-06-01  | a
InformationsquelleAutor user2765924 | 2013-09-10

7 Kommentare

  1. 75

    Cómo acerca de algo como

    SELECT mt.*,     
    FROM MyTable mt INNER JOIN
        (
            SELECT ID, MIN(Record_Date) MinDate
            FROM MyTable
            GROUP BY ID
        ) t ON mt.ID = t.ID AND mt.Record_Date = t.MinDate

    Esto hace que la fecha mínima por ID y, a continuación, se obtienen los valores basados en esos valores. La única vez que usted tendría duplicados es si hay duplicados mínimo record_dates para el mismo ID.

    • Ah, que inicialmente estaba usando una expresión para la salida de una fecha que fue el causante de la ‘y’ condición en el inner join para que no funcionen correctamente. Cambió a una columna real y funciona ahora (y tuve que modificar algunas otras cosas, como un resultado), gracias!
    • esto no funciona cuando dos registros de la misma id y la fecha en que se presente, obtendrá varias filas a la derecha?
  2. 13

    Que yo pudiera llegar a su resultado esperado con sólo hacer esto en :

     SELECT id, min(record_date), other_cols 
      FROM mytable
      GROUP BY id

    Hace este trabajo para usted?

    • Por la razón que sea, esto parece funcionar en el ejemplo inventado (sqlfiddle.com/#!2/f8469/6/0), pero en la práctica me sale «Columna» de la base de datos.tabla.col_name’ no es válida en la lista de selección porque no está contenida en una función de agregado ni en la cláusula GROUP BY.» Yo era capaz de hacerlo funcionar con astander la respuesta de todos modos, gracias.
    • Sí, yo estoy en el mismo problema, me gustaría una respuesta simple como este en SQL Server
  3. 6

    Para obtener el producto más barato en cada categoría, se utiliza la función MIN() en una subconsulta correlacionada de la siguiente manera:

        SELECT categoryid,
           productid,
           productName,
           unitprice 
        FROM products a WHERE unitprice = (
                    SELECT MIN(unitprice)
                    FROM products b
                    WHERE b.categoryid = a.categoryid)

    La consulta externa examina todas las filas en la tabla de productos y devoluciones de los productos que tienen precios unitarios coincidir con el precio más bajo en cada categoría devueltos por la subconsulta correlacionada.

  4. 1

    Esto no es simplemente:

    select t2.id,t2.record_date,t2.other_cols 
    from (select ROW_NUMBER() over(partition by id order by record_date)as rownum,id,record_date,other_cols from MyTable)t2 
    where t2.rownum = 1
  5. 1

    Me gustaría añadir que algunas de las otras respuestas aquí, si usted no necesita la primera elemento, pero dicen que el segundo número, por ejemplo, puede utilizar rownumber en una subconsulta y de la base de que el conjunto de resultados a partir de eso.

    SELECT * FROM
    (
        SELECT
            ROW_NUM() OVER (PARTITION BY Id ORDER BY record_date, other_cols) as rownum,
            *
        FROM products P
    ) INNER
    WHERE rownum = 2

    Esto también permite a pedido de varias columnas en la subconsulta que puede ayudar si dos record_dates tienen valores idénticos. También puede dividir de varias columnas, si es necesario por la delimitación de ellos con una coma

  6. 0

    Esta una vieja pregunta, pero esto puede ser útil para alguien
    En mi caso no puedo usar una sub consulta porque tengo una gran consulta y necesito utilizando min() en mi resultado, si yo uso la sub consulta a la db necesario ejecutar de nuevo mi gran consulta. estoy usando Mysql

    select t.* 
        from (select m.*, @g := 0
            from MyTable m --here i have a big query
            order by id, record_date) t
        where (1 = case when @g = 0 or @g <> id then 1 else  0 end )
              and (@g := id) IS NOT NULL

    Básicamente me ordenó el resultado y, a continuación, poner una variable con el fin de obtener el primer registro en cada grupo.

  7. 0

    La siguiente consulta, toma la primera fecha para cada orden de trabajo (en una tabla que muestra todos los cambios de estado):

    SELECT
        WORKORDERNUM,
        MIN(DATE)
    FROM
        WORKORDERS
    WHERE
        DATE >= to_date('2015-01-01','YYYY-MM-DD')
    GROUP BY
        WORKORDERNUM

Kommentieren Sie den Artikel

Bitte geben Sie Ihren Kommentar ein!
Bitte geben Sie hier Ihren Namen ein

Pruebas en línea