简体   繁体   中英

How to only SELECT data if a specific record is not exist

I'm trying to display multiple of data with a condition and skip rows if a specific record is exist in the same table in MySQL.

Here's example of the table

table_a

|      id     |     bi_id    |     status     |
|-------------|--------------|----------------|
|          1  |         111  |process1        |
|          2  |         112  |process1        |
|          3  |         112  |process2        |
|          4  |         113  |process1        |
|          5  |         111  |process2        |
|          6  |         111  |done            |
|          7  |         112  |done            |

I'm using this query below to select last id with status "done"

SELECT MAX(id) FROM table_a WHERE status="done" GROUP BY bi_id

The struggle is where I want to display last id where the status is not "done" and dont select max id if bi_id with status "done" is exist, like this table below.

Expected result:

------------------
|    max(id)     |
|----------------|
|       4        |

My last try was using this query but as you know this is not gonna work. I also have tried query with NOT EXIST and not working either.

SELECT MAX(id)
FROM   table_a
WHERE status != "done" NOT IN
     (SELECT id
     FROM   table_a
     WHERE  status = "done" GROUP BY bi_id) GROUP BY by_id

Is there any workaround to achieve that with MySQL query or php/codeigniter? Thanks and sorry for bad english.

Try this query:

SELECT MAX(`id`)
FROM `table_a`
WHERE `status` != 'done'
AND `bi_id` NOT IN (
  SELECT `t2`.`bi_id`
  FROM `table_a` AS `t2`
  WHERE `t2`.`status` = 'done'
);

In this way you exclude the rows with bi_id with status = 'done' . You can see the result in this DBFiddle .

You could do a query this simple:

SELECT MAX(id)
 FROM table_a
 GROUP BY bi_id
HAVING GROUP_CONCAT(status) NOT LIKE '%done%'

In the query example above, I'm making use of the GROUP BY and GROUP_CONCAT() function. Basically, what I'm doing with the query is:

SELECT bi_id, GROUP_CONCAT(status), MAX(id) 
 FROM table_a
 GROUP BY bi_id;

Which will return:

+-------+------------------------+---------+
| bi_id | GROUP_CONCAT(status)   | MAX(id) |
+-------+------------------------+---------+
| 111   | process1,process2,done |    6    |
| 112   | process1,process2,done |    7    |
| 113   | process1               |    4    |
| 114   | process2,process1      |   10    |
+--------------------------------+---------+

As you can see, the bi_id for both 111 & 112 have result of GROUP_CONCAT(status) inclusive of done in it. Therefore, these two are filtered out during the query HAVING GROUP_CONCAT(status) LIKE '%done%' .

Demo fiddle

P/S: Taking consideration of the last comment, I've added two additional rows in the example (8,114,'process2'), (10,114,'process1') .

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