From this dataset:
mysql> SELECT * FROM document_signature;
+----+-------------+-------------+---------+-------+-----------+
| id | document_id | employee_id | user_id | order | status |
+----+-------------+-------------+---------+-------+-----------+
| 1 | 1 | 2 | NULL | 0 | SIGNED |
| 2 | 1 | 3 | NULL | 1 | NOTSIGNED |
| 3 | 1 | 4 | NULL | 1 | NOTSIGNED |
| 4 | 2 | 3 | NULL | 0 | NOTSIGNED |
| 5 | 3 | NULL | 1 | 0 | SIGNED |
| 6 | 3 | 1 | NULL | 0 | NOTSIGNED |
+----+-------------+-------------+---------+-------+-----------+
6 rows in set (0.00 sec)
I want to find the rows that have the minimun order
, but only from those whose status is NOTSIGNED
, even if there is more than one for each document_id
Using this query:
SELECT s.*
FROM document_signature s
WHERE `order` =
(SELECT MIN(s2.`order`)
FROM document_signature s2
WHERE s.document_id = s2.document_id
AND s2.status = 'NOTSIGNED');
These are the results I’m getting:
+----+-------------+-------------+---------+-------+-----------+
| id | document_id | employee_id | user_id | order | status |
+----+-------------+-------------+---------+-------+-----------+
| 2 | 1 | 3 | NULL | 1 | NOTSIGNED |
| 3 | 1 | 4 | NULL | 1 | NOTSIGNED |
| 4 | 2 | 3 | NULL | 0 | NOTSIGNED |
| 5 | 3 | NULL | 1 | 0 | SIGNED |
| 6 | 3 | 1 | NULL | 0 | NOTSIGNED |
+----+-------------+-------------+---------+-------+-----------+
5 rows in set (0.00 sec)
My question is: Why is there a row with status
SIGNED
in the resultset, what am I doing wrong here?
2
Answers
Although, both
document_id=3
have differentstatus
, they have the sameorder
value. Therefore, yourMIN()
result is actually true for bothstatus
. The quick way workaround here is to add anotherstatus='NOSIGNED'
condition like so:Demo fiddle
There is actually more than one way to do this on MySQL v8+, here is one:
On your current sample data, this may look no different but let’s say if we add two more rows in the table:
it will become like this:
Then, when you run the subquery of:
you’ll get this result:
Notice that for
id = 7 & 8
, the value inmin_ord
is not the same as theirorder
value. That’s when you make that query as derived table and do theWHERE s.order=s.min_ord
comparison.There’s another example in this fiddle using cte
You can use the following query even if you are using MySQL v4 :
Edit1: