Yes, you could use one table to track both sold and unsold items. It would be like a transaction table in an OLTP, with the distinction that the transaction remains open until the sale is closed. In theory that's a good idea, as that would be 3NF (assuming listings and sales are 1-1), but it practice it's more common to denormalize the for sale listings from the actual sale transactions. There are several practical reasons for this, I can elaborate if you need to justify the decision.
If decide to combine them into one table, it would be a sale_transactions table with a many-to-many relationship to users. The buyer_user_id would be null until the item was sold, and it should also include things like product_id, listing_price, listing_date, sale_date and taxes.
If you're willing to separate the tables, you would have a for_sale table and a sales_history (or just sales or similar) table. You might want to combine the sales_history with the orders table, it depends on the way you plan to populate them.
- In the for_sale table is the listing_id, listing_user_id, product_id, list_price, listing_date and units_available. This represents the items for sale, and has the advantage of having only one row with multiple units for sale (whereas a combined sale_transaction table as above would only work for individual units.) As units are sold, the available_units goes down until it reaches zero. At that point you can either leave the row for historical records, or remove it. (Though multiple units might not apply to this case, if sellers usually only have one copy of a book.)
- In the sales_history table is the listing_id, the buyer_user_id, the sale_date, and probably the order_id (depends how you want to associate orders to sales.)
So the buy/sell scenarios would be:
- User lists a book for sale. New entry in the for_sale table with the product, seller, etc.
- User searches for books for sale. Query the for_sale table joined to the products and categories tables to get a listing of all products for sale and their details.
- User buys a book. New entry in the sales_history table with the listing, the buyer, etc. Entry in the for_sale table is updated to decrement the units_available by 1. (Or else delete the row, mark it sold with a flag, or some other way to indicate it's not available.)