Tengo dos tablas llamadas 'Clientes' y 'Pedidos'. Los nombres de las columnas de las tablas son los siguientes:

Customers: id, name, address
Orders: id, person_id, product, price 

El resultado deseado es consultar a todos los clientes con una de sus últimas compras. Tengo muchos duplicados en la tabla 'Órdenes' por la cual dos registros con la misma marca de tiempo debido a algún error.

He escrito el siguiente código, pero el problema es que la consulta no devuelve los valores de columna de la tabla 2 (Pedidos). ¿Alguien puede aconsejar cuál es el problema?


SELECT C.Id,C.Name, O.item, O.price, O.product
FROM Customers C
LEFT JOIN
    (
        SELECT TOP 1 person_id
        FROM Orders 
        WHERE status = 'Pending'
    ) O ON C.ID = O.person_id

Results:  O.item, O.price, O.product values are all null 

Editar: Datos de muestra

ID / NOMBRE / DIRECCIÓN /
1 / A / Ad1 /
2 / B / Ad2 /
3 / C / Ad3 /

ID / ID de persona / PRECIO DEL PRODUCTO / Fecha de creación
ID-1234/1 / Libro / $ 5 / 26-2-2017
ID-1235/1 / Libro / $ 5 / 26-2-2017
ID-1236/2 / Calendario / $ 10 / 4-2-2017
ID-1238/1 / Bolígrafo / $ 2 / 1-1-2016

0
Hue 26 feb. 2017 a las 06:25

2 respuestas

La mejor respuesta

Suponiendo que la columna id en Orders es un incremento automático de clave principal, entonces lo siguiente debería funcionar:

SELECT c.id,
       c.name,
       COALESCE(t1.price, 0.0) AS price,
       COALESCE(t1.product, 'NA') AS product
FROM Customers c
LEFT JOIN Orders t1
    ON c.id = t1.person_id
LEFT JOIN
(
    SELECT person_id, MAX(CAST(SUBSTRING(id, 4, LEN(id)) AS INT)) AS max_id
    FROM Orders
    GROUP BY person_id
) t2
    ON t1.person_id = t2.person_id AND
       t2.max_id    = CAST(SUBSTRING(t1.id, 4, LEN(t1.id)) AS INT)

Esta respuesta supone que tomar la mejor identificación de pedido por cliente generará la compra más reciente. Idealmente, debe tener una columna de marca de tiempo que capture cuándo se realizó una transacción. Tenga en cuenta que incluso en la consulta anterior, todavía no tenemos forma de saber cuándo se realizó la transacción más reciente.

1
Tim Biegeleisen 26 feb. 2017 a las 08:38

Entonces, ¿dónde está la columna timestamp? No se menciona en el esquema de su tabla. Pero su descripción tampoco menciona la columna status, y eso está claramente ahí.
¿Es orders.id único? ¿Es la clave de la tabla Orders?> Si lo es, entonces su esquema no tiene forma de identificar registros "duplicados". No puede querer decir que solo se permite un pedido por cliente, por lo que si hay varios pedidos para un solo cliente, ¿cómo identificamos los duplicados? ¿Por la columna timestamp no mencionada?

Si hay una columna de `marca de tiempo, y así es como identificarías a los engañados, úsalo.

SELECT C.Id,C.Name, O.item, O.price, O.product
FROM Customers C LEFT JOIN Orders o
   on o.id = (Select Min(id) from orders
              where person_id = c.Id
                and timestamp = o.timestamp
                and status = 'Pending')
0
Charles Bretana 26 feb. 2017 a las 03:38