Tengo la situación:

Table1 has a list of companies.
Table2 has a list of addresses.
Table3 is a N relationship of Table1 and Table2, with fields 'begin' and 'end'.

Porque las empresas pueden mover a lo largo del tiempo, un LEFT JOIN entre ellos los resultados en varios registros para cada empresa.

begin y end campos nunca son NULOS. La solución para encontrar la dirección más reciente es el uso de una ORDER BY being DESC, y para quitar mayores de direcciones es un LIMIT 1.

Que funciona bien si la consulta puede llevar sólo 1 empresa. Pero tengo una consulta que trae todos los registros de la Tabla1, se unió con su actual Tabla2 direcciones. Por lo tanto, la eliminación de los datos debe realizarse (AFAIK) en la IZQUIERDA de la combinación EN la cláusula.

Alguna idea de cómo puedo construir la cláusula de no crear duplicados Tabla1 empresas y traer la última dirección?

OriginalEl autor Hikari | 2014-02-17

2 Comentarios

  1. 14

    Utilizar un dependiente de la subconsulta con la función max() en una condición de combinación.

    Algo como en este ejemplo:

    SELECT *
    FROM companies c
    LEFT JOIN relationship r
    ON c.company_id = r.company_id
       AND r."begin" = (
            SELECT max("begin")
            FROM relationship r1
            WHERE c.company_id = r1.company_id
         )
    INNER JOIN addresses a
    ON a.address_id = r.address_id 

    demo: http://sqlfiddle.com/#!15/f80c6/2

    Agradable en sqlfiddle – sólo he visto jsfiddle hasta ahora, pero sqlfiddle parece superhelpful!

    OriginalEl autor krokodilko

  2. 5

    He conseguido resolverlo utilizando la Función de Windows:

    WITH ranked_relationship AS(
        SELECT
            *
            ,row_number() OVER (PARTITION BY fk_company ORDER BY dt_start DESC) as dt_last_addr
        FROM relationship
    )
    
    SELECT
        company.*
        address.*,
        dt_last_addr as dt_relationship
    FROM
        company
        LEFT JOIN ranked_relationship as relationship
                ON relationship.fk_company = company.pk_company AND dt_last_addr = 1
        LEFT JOIN address ON address.pk_address = relationship.fk_address

    row_number() crea un int contador para cada registro, dentro de cada ventana de acuerdo a fk_company. Para cada ventana, el registro con la fecha más reciente en primer lugar viene con el rango 1, entonces dt_last_addr = 1 se asegura de que la combinación ocurre sólo una vez para cada fk_company, con el registro con la dirección más reciente.

    Las Funciones de la ventana son muy potentes y en pocos ppl uso de ellos, evitar muchas combinaciones complejas y subconsultas!

    OriginalEl autor Hikari

Dejar respuesta

Please enter your comment!
Please enter your name here