2009-09-02 13 views
12

Tengo 2 tablas, una tabla de "documento" y una tabla de "contenido". Son similares a esto (simplificado):Mostrar solo la fecha más reciente de la tabla MySQL unida

document table: 
docID 
docTitle 

content table: 
contentID 
docID 
dateAdded 
content 

Por cada cambio de contenido, un nuevo registro se inserta en la tabla "contenido". De esta manera hay un historial completo de todos los cambios. Me gustaría obtener una lista de todos los documentos, con los últimos contenidos unidos. Debería devolver el docID, el docTitle y el registro de contenido asociado con el valor "fechaAdición" más reciente. Mi cerebro me está fallando en este momento, ¿cómo podría crear esta unión?

+2

Tal vez cambiar el nombre de esta pregunta a algo más descriptivo, como "Mostrar sólo la fecha más reciente de la tabla unida"? –

+0

@Gorgapor: Buena llamada, he actualizado el título. –

Respuesta

26

Esto se puede hacer con una subconsulta:

SELECT d.docID, docTitle, c.dateAdded, c.content 
FROM document d LEFT JOIN content c ON c.docID = d.docID 
WHERE dateAdded IS NULL 
    OR dateAdded = (
     SELECT MAX(dateAdded) 
     FROM content c2 
     WHERE c2.docID = d.docID 
    ) 

Esto se conoce como una consulta "groupwise maximum"

Editar: Hecho la consulta devolver todas las filas de documentos, con nulos si no hay contenido relacionado.

+2

Gracias por el nombre. Cada vez que tengo una pregunta de SQL, nunca sé qué buscar en Google, lo que hace que sea más difícil encontrar una solución. :) –

+0

¿Funcionaría esta consulta cuando no hay registros de contenido para un documento? Todavía me gustaría que aparezca el documento, y simplemente devuelvo nulo para la fecha de los campos Agregados y de contenido. –

+0

actualizó la consulta para devolver todas las filas del documento –

0

¿No podría simplemente hacer una unión simple y ordenar por fecha agregada, y tomar solo el primer registro?

SELECT docTable.docId, docTable.docTitle from docTable 
INNER JOIN content ON content.docID = docTable.contentID 
WHERE docTable.docId = <some id> 
ORDER BY content.dateAdded DESC 
+0

Creo que quiere que la orden sea DESC, por lo que la versión más nueva es la primera. Además, si agrega "LIMIT 1", obtendrá una sola fila. – Craig

+0

Su derecho sobre la orden. En cuanto al límite, también tienes razón, lo dejé porque no estaba seguro de la tecnología de la base de datos. Ese comando puede variar (hasta donde yo sé). – Zoidberg

-1

Esta es una solución al 2 consulta:

Primera consulta:

select docID, max(dateadded) from [TblContent] group by docID 

Segunda consulta:

select [TblDocument].* from [TblDocument] 
inner join [TblDocument] on [TblDocument].[Docid]=[FirstQuery].[DocID] 
+0

Esto requeriría una consulta separada para cada fila, no solo dos consultas. –

-1

intente esto:

select d.id, d.docTitle, MAX(c.dateAdd) 
from document_table d 
left join content_table c 
on d.id = c.docId 
group by d.id 

Aquí es el pensamiento detrás de él: superficie para documentos supongamos que tiene un registro A en relación con el contenido (1, 2, 3, 4) y B en relación con (5, 6, 7, 8)

document  content 

A    1 
      2 
        3 
      4 

B    5 
      6 
      7 
      8 

unirse a un interno con un máximo (dateadded) le dará

document  content  max(dateadded) 

A    1   1-1-2009... 

A    2   1-1-2009... 

A    3   1-1-2009... 

A    4   1-1-2009... 

B    5   2-1-2009... 

B    6   2-1-2009... 

B    7   2-1-2009... 

B    8   2-1-2009... 

tras grupo por documento de identificación obtendrá

document content  max(dateadded) 

A   1   1-1-2009... 

B   5   2-1-2009... 

nota: Identificación del contenido no es necesario coincidir con el ID del máximo dateadded

+0

¿Es posible devolver documentos que no tienen registros de contenido asociados aún cambiando esto a una combinación externa, o cambiará el comportamiento? Además, ¿puede esto devolver los campos contentID y content incluyéndolos en el select, o eso lo estropeará? –

+0

¿Es este Mi Sql? Porque si no es así, dependiendo de la base de datos, es posible que no pueda seleccionar nada que no esté en la cláusula group by. – Zoidberg

+0

puede hacer la combinación izquierda, pero no puede poner allí la columna contentID. –

4

Uso:

SELECT t.docid, 
     t.docTitle, 
     mc.dateAdded, 
     mc.content 
    FROM DOCUMENT t 
    JOIN (SELECT c.docid, 
       c.content, 
       MAX(c.dateAdded) 
      FROM CONTENT c 
     GROUP BY c.docid, c.content) mc ON mc.docid = t.docid 
            AND mc.dateadded = t.dateadded 

Esto debería ser más rápido que una consulta correlacionada.

alternativa para cuando no hay registros de contenido de un documento:

SELECT t.docid, 
      t.docTitle, 
      mc.dateAdded, 
      mc.content 
    FROM DOCUMENT t 
LEFT JOIN (SELECT c.docid, 
        c.content, 
        MAX(c.dateAdded) 
      FROM CONTENT c 
     GROUP BY c.docid, c.content) mc ON mc.docid = t.docid 
            AND mc.dateadded = t.dateadded 
Cuestiones relacionadas