简体   繁体   中英

MySQL Select one row with unique attribute value

I'm building a stock keeping system and decided to store each product's balance (everytime it's updated) into the following table:

+------------+--------------+---------+------+
| Product_id | Warehouse_id | Balance | Date |
+------------+--------------+---------+------+

Example:

Staff adds 10 pieces to product_id 123 in warehouse_id 5

+------------+--------------+---------+-------------+
| Product_id | Warehouse_id | Balance | Date        |
+------------+--------------+---------+-------------+
| 123        | 5            | 10      | 2013-09-16  |
+------------+--------------+---------+-------------+

Staff then adds 3 pieces to product 234 in warehouse_id 5, and 5 pieces to 123 in warehouse_id 5,

+------------+--------------+---------+-------------+
| Product_id | Warehouse_id | Balance | Date        |
+------------+--------------+---------+-------------+
| 123        | 5            | 10      | 2013-09-16  |
| 234        | 5            | 3       | 2013-09-18  |
| 123        | 5            | 15      | 2013-09-21  |
+------------+--------------+---------+-------------+

*Notice the date column

Now let me add a few more rows

+------------+--------------+---------+-------------+
| Product_id | Warehouse_id | Balance | Date        |
+------------+--------------+---------+-------------+
| 123        | 5            | 10      | 2013-09-16  |
| 234        | 5            | 3       | 2013-09-18  |
| 123        | 5            | 15      | 2013-09-21  |
| 123        | 5            | 18      | 2013-09-24  |
| 234        | 5            | 10      | 2013-09-26  |
| 123        | 5            | 22      | 2013-09-29  |
+------------+--------------+---------+-------------+

How do i run a query that would get me all products' balances as at 25th of September 2013?

That means i need the following result:

+------------+--------------+---------+-------------+
| Product_id | Warehouse_id | Balance | Date        |
+------------+--------------+---------+-------------+
| 234        | 5            | 3       | 2013-09-18  |
| 123        | 5            | 18      | 2013-09-24  |
+------------+--------------+---------+-------------+

In short I need the latest row (by date), per product_id.

Any help would be greatly appreciated!

Assuming that products' balances are being maintained per warehouse you can do it like this

SELECT t.product_id, t.warehouse_id, t.balance, t.date
  FROM table1 t JOIN 
(
  SELECT warehouse_id, product_id, MAX(date) date
    FROM table1
   WHERE date <= '2013-09-25'
   GROUP BY warehouse_id, product_id
) q
    ON t.warehouse_id = q.warehouse_id
   AND t.product_id = q.product_id
   AND t.date = q.date

Output:

| PRODUCT_ID | WAREHOUSE_ID | BALANCE |       DATE |
|------------|--------------|---------|------------|
|        234 |            5 |       3 | 2013-09-18 |
|        123 |            5 |      18 | 2013-09-24 |

Here is SQLFiddle demo

SELECT * 
FROM TABLE 
WHERE (PRODUCT_ID, DATE) IN
     (SELECT PRODUCT_ID, MAX(DATE) FROM TABLE
      WHERE DATE <= '2013-09-25'     
       GROUP BY PRODUCT_ID )

Query:

SQLFIDDLEExample

  SELECT *
  FROM table1 t 
  WHERE t.`Date` = (SELECT MAX(t2.`Date`)
                  FROM Table1 t2
                  WHERE t2.`Date` <= '2013-09-25'
                  AND t2.product_id = t.product_id)

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