So I have a weird situation in which I have a table like this :
mysql> select * from test;
------- ------
| name | sal |
------- ------
| john | 1000 |
| john | 2000 |
| NULL | 3000 |
| NULL | 4000 |
| smith | 5000 |
| smith | 6000 |
| neo | 7000 |
------- ------
I want to return a data set which looks like this :
------- ------
| name | sal |
------- ------
| john | 1000 |
| NULL | 3000 |
| NULL | 4000 |
| smith | 5000 |
| neo | 7000 |
------- ------
Meaning I want to fetch unique rows wherever name is duplicated, but fetch all rows as it is when name is null or is not duplicated.
I have written this query below in order to achieve that and it works fine. But I want to optimize it.
select *
from test
where sal in (
select sal from (
select min(sal) as sal
from test
group by name
union
select sal
from test where name is null
) t
order by sal);
Queries for creating this sample data -
create table test (name text, sal int);
insert into test values ('agent',1000);
insert into test values ('agent',2000);
insert into test values (null,3000);
insert into test values (null,4000);
insert into test values ('smith',5000);
insert into test values ('smith',6000);
insert into test values ('neo',7000);
Can anyone help me with that? I know that we shouldn't use IN to fetch data because that will increase the query time a lot in production.
Any help is appreciated!
CodePudding user response:
You can try to use two queries with UNION ALL one is for name which value is null, another one writes MIN aggregate function by name with name isn't NULL.
Query #1
SELECT *
FROM (
SELECT name,sal
FROM test
WHERE name IS NULL
UNION ALL
SELECT name,min(sal)
FROM test
WHERE name IS NOT NULL
group by name
)t1
ORDER BY sal;
| name | sal |
|---|---|
| agent | 1000 |
| 3000 | |
| 4000 | |
| smith | 5000 |
| neo | 7000 |
Note
You can try to create an index on name column which might help you improve the query performance
