简体   繁体   中英

SQL LEFT JOIN - Inner select not returning columns

I have two tables called 'Customers' and 'Orders'. Tables column names are as follow:

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

The desired outcome is to query all customers with one of their latest purchases. I have a lot of duplicates in 'Orders' table whereby two records with same time-stamp due to some bug.

I have written the following code but the issue is that the query does not return table 2(Orders) column values. Can anyone advise what the issue is?


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 

Edit: Sample Data

ID/ NAME/ ADDRESS/
1/ A/ Ad1/
2/ B/ Ad2/
3/ C/ Ad3/

ID/ Person ID/ PRODUCT PRICE/ Created Date
ID-1234/ 1/ Book/ $5/ 26-2-2017
ID-1235/ 1/ Book/ $5/ 26-2-2017
ID-1236/ 2/ Calendar/ $10/ 4-2-2017
ID-1238/ 1/ Pen/ $2/ 1-1-2016

Assuming that the id column in Orders is a primary key autoincrement, then the following should work:

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)

This answer assumes that taking the greatest order ID per customer will yield the most recent purchase. Ideally you should have a timestamp column which captures when a transaction took place. Note that even in the query above, we still have no way of knowing when the most recent transaction took place.

So where is the timestamp column? It's not mentioned in your table schema. But your description does not mention the status column either, and that is clearly in there.
Is orders.id unique? Is it the key for the Orders table?> If it is, then your schema has no way to identify "duplicate" records. You cannot mean to imply that only one order per customer is allowed, so if there are multiple orders for a single customer, how do we identify the duplicates? By the unmentioned timestamp column?

If there IS a `timestamp column, and that's how you would identify dupes, then use it.

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')

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM