Summary: in this tutorial, you will learn how to compare successive rows within the same table in MySQL.
Setting up sample data
First, create a new table called inventory:
CREATE TABLE inventory(
id INT AUTO_INCREMENT PRIMARY KEY,
counted_date date NOT NULL,
item_no VARCHAR(20) NOT NULL,
qty INT NOT NULL
);Code language: SQL (Structured Query Language) (sql)In the inventory table:
- The
idis an auto-increment column. - The
counted_dateis the counted date. - The
item_nois the item code posted to inventory. - The
qtyis the accumulated on-hand quantity in inventory.
Second, insert some rows into the inventory table:
INSERT INTO inventory(counted_date,item_no,qty)
VALUES ('2014-10-01','A',20),
('2014-10-02','A',30),
('2014-10-03','A',45),
('2014-10-04','A',80),
('2014-10-05','A',100);Code language: SQL (Structured Query Language) (sql)Third, retrieve data from the inventory table:
SELECT * FROM inventory;Output:
+----+--------------+---------+-----+
| id | counted_date | item_no | qty |
+----+--------------+---------+-----+
| 1 | 2014-10-01 | A | 20 |
| 2 | 2014-10-01 | A | 30 |
| 3 | 2014-10-01 | A | 45 |
| 4 | 2014-10-01 | A | 80 |
| 5 | 2014-10-01 | A | 100 |
+----+--------------+---------+-----+
5 rows in set (0.00 sec)Code language: JavaScript (javascript)If you want to determine the received quantity of item A of a particular day, you need to compare the on-hand quantity of that day with its preceding day.
In other words, you need to compare each row with its consecutive row in the inventory table to calculate the difference.
Comparing the current row with the next row within the same table
The following query uses a Common Table Expression (CTE) and the LAG window function to calculate the received quantity of items per day by comparing the on-hand quantity of a particular day with its successive day:
WITH cte AS (
SELECT
item_no,
counted_date from_date,
LEAD(counted_date, 1) OVER ( ORDER BY counted_date) to_date,
qty,
LEAD(qty, 1) OVER (ORDER BY counted_date) new_qty
FROM
inventory
)
SELECT
item_no,
from_date,
to_date,
(new_qty - qty) AS received_qty
FROM
cte
WHERE
to_date IS NOT NULL;Code language: SQL (Structured Query Language) (sql)Output:
+---------+------------+------------+--------------+
| item_no | from_date | to_date | received_qty |
+---------+------------+------------+--------------+
| A | 2014-10-01 | 2014-10-02 | 10 |
| A | 2014-10-02 | 2014-10-03 | 15 |
| A | 2014-10-03 | 2014-10-04 | 35 |
| A | 2014-10-04 | 2014-10-05 | 20 |
+---------+------------+------------+--------------+
4 rows in set (0.00 sec)Code language: JavaScript (javascript)How it works.
First, define the cte common table expression to simplify the subsequent query:
WITH cte AS (
SELECT
item_no,
counted_date from_date,
LEAD(counted_date, 1) OVER ( ORDER BY counted_date) to_date,
qty,
LEAD(qty, 1) OVER (ORDER BY counted_date) new_qty
FROM
inventory
) Code language: SQL (Structured Query Language) (sql)The CTE selects the following columns from the inventory table:
item_no: The item number.counted_date: The date of counting.LEAD(counted_date, 1) OVER (ORDER BY counted_date) AS TO_DATE: It uses theLEADwindow function to get the nextcounted_dateorder bycounted_date, which returns theto_date.qty: The number of items on the current day.LEAD(qty, 1) OVER (ORDER BY counted_date) AS new_qty: It uses theLEADwindow function to get the number of items on the next day, which returns thenew_qty.
Second, retrieve data from the cte to form the desired result set:
SELECT
item_no,
from_date,
to_date,
(new_qty - qty) AS received_qty
FROM
cte
WHERE
to_date IS NOT NULL;Code language: SQL (Structured Query Language) (sql)The query selects columns from the cte:
item_no: The item number.from_date: The counted date, which is considered as the starting date.to_date: The counted date of the next day, obtained using theLEADfunction in the CTE.new_qty - qty AS received_qty: Calculates the received quantity by subtracting the current day’s quantity (qty) from the next day’s quantity (new_qty).WHERE to_date IS NOT NULL: Filters the results to exclude the last day where there is no next day.
Summary
- Use a
CTEandLAGwindow function to compare successive rows within the same table.