Mysql select query using NOT IN / LIKE to retrieve the data - mysql

I need to fetch the data in mysql using select query as below
Select tid from abc where abc.parameter not like '%DONE%'
But data return where parameter column have %DONE% VALUE.
Here I am giving sample data for better understanding
tid parameter value
***************************
1 abc 123
1 def 456
1 ghi 789
I need to retrieve tid where def not in .

Schema
create table abc
( id int auto_increment primary key,
tid int not null,
parameter varchar(20) not null,
value int not null
);
insert abc(tid,parameter,value) values (1,'abc',123),(1,'def',456),(1,'ghi',789);
Queries
select id,tid from abc where abc.parameter not like '%DONE%';
+----+-----+
| id | tid |
+----+-----+
| 1 | 1 |
| 2 | 1 |
| 3 | 1 |
+----+-----+
select id,tid from abc where abc.parameter not like '%abc%';
+----+-----+
| id | tid |
+----+-----+
| 2 | 1 |
| 3 | 1 |
+----+-----+
Looks as expected to me.
Note, NOT IN is dangerous in the case of NULLs. One must know there data well, else use NOT EXISTS

Your tid is same, the returned data might be right, but due to ambiguity in your tid you feel that you are getting wrong result.

Related

How to loop through an array in SQL where clause?

I have a MySQL table which has the following columns and records:
| Name | Total | GivenBy |
| ---- | -------- | ------------ |
| Z | 200 |['A','B','C'] |
| X | 240 |['A','D','C'] |
I would like to extract Record No. 1 on the basis of 3rd column where the SQL query would be like:
SELECT * FROM mytable WHERE GivenBy='B';
Is there a way I can loop through the list in third column and take out the respective string as required in the SQL WHERE clause in a single query?
Please note that I cannot add more columns in the table.
If you can please provide the query as MySQL compatible, I would really appreciate it.
The "array" you show isn't quite valid JSON, but if you use double-quotes instead of single-quotes, you can use JSON_TABLE() to do this:
CREATE TABLE MyTable
(
Name CHAR(1) PRIMARY KEY,
Total INT NOT NULL,
GivenBy JSON NOT NULL
);
INSERT INTO MyTable VALUES
('Z', 200, '["A","B","C"]'),
('X', 240, '["A","D","C"]');
SELECT Name, Total, g.Value
FROM MyTable
CROSS JOIN JSON_TABLE(GivenBy, '$[*]' COLUMNS(Value CHAR(1) PATH '$')) AS g;
+------+-------+-------+
| name | total | value |
+------+-------+-------+
| X | 240 | A |
| X | 240 | D |
| X | 240 | C |
| Z | 200 | A |
| Z | 200 | B |
| Z | 200 | C |
+------+-------+-------+
But the best choice is not to store "arrays" in MySQL. Store the values one per row in a second table.
You can use the "like" keyword with regex to match your requirements in the third column.
select * from table where givenBy like "%B%";
Something similar would work.
You need to run a script:
Retrieve the list of unique values in the GivenBy column using the following query:
SELECT DISTINCT JSON_EXTRACT(GivenBy, '$[*]') AS GivenByValues
FROM mytable;
Loop through the list of unique values, and for each value, run a query that uses that value in the WHERE clause:
SELECT *
FROM mytable
WHERE JSON_SEARCH(GivenBy, 'one', [current_value_from_loop]) IS NOT NULL;

Mysql query to get distinct row with column having null and duplicate values

So I have a weird situation in which I have a table like this :
mysql> select * from test;
+-------+------+
| name | sal |
+-------+------+
| agent | 1000 |
| agent | 2000 |
| NULL | 3000 |
| NULL | 4000 |
| smith | 5000 |
| smith | 6000 |
| neo | 7000 |
+-------+------+
I want to return a data set which looks like this :
+-------+------+
| name | sal |
+-------+------+
| agent | 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!
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
View on DB Fiddle
Note
You can try to create an index on name column which might help you improve the query performance

MySQL not retrieving data when using an OR clause on VARCHAR type

Real Final edit (since it seems like people think is a null :P):
Let me rephrase it, since it is hard to explain and it seems no one can help me. I made 2 stored procedures in MySQL with phpMyAdmin. Both with an IN parameter VARCHAR(500) in utf8, var1.
With a value of 'novalue' for the In parameter these are the behaviours:
tableA:
------------------
a | b | example
------------------
1 | A | 1
2 | A | 1
3 | T | 1
SELECT * FROM tableA
WHERE (var1 = 'novalue')
SELECT * FROM tableA
WHERE (var1 = 'novalue' OR var1 = tableA.col1)
Expected output (Only first procedure will give me this result):
------------------
a | b | example
------------------
1 | A | 1
2 | A | 1
3 | T | 1
So my problem is, how to get the same expected output on the second procedure?
Thanks in advance

Select from table A if not exist then table B

I have two tables as bellow,
table A:
+------+----------------+
| TYPE | EMAIL |
+------+----------------+
| 0 | test1#mail.com |
| 1 | test2#mail.com |
| 2 | test3#mail.com |
table B:
+------+----------------+
| ID | EMAIL |
+------+----------------+
| 1 | test1#mail.com |
| 2 | test4#mail.com |
| 3 | test5#mail.com |
I need to check the email address from both table with following criteria,
Check in the table A, IF EXISTS select the TYPE
IF it is not in table A, then check it in table B select the ID
even it is not in table B empty results as normal select query
I can do this with two quires, But my question is whether there is any possibility to do it with one single query ?
Thanks in advance.
This is an alternative: I hope it can be useful anyway.
(SELECT NULL AS ID, EMAIL, TYPE FROM A WHERE EMAIL=<email>)
UNION
(SELECT ID, EMAIL, NULL AS TYPE FROM B WHERE EMAIL=<email>)
In your application you will retrieve from 0 to 2 results. If you got 1 result, use it (note that you will have a NULL value in ID or TYPE). If you got 2 results, use the one where the TYPE is not NULL.
Using your dataset and "test1#mail.com" as the query parameter, this would be the result of the query:
ID EMAIL TYPE
NULL test1#mail.com 0
1 test1#mail.com NULL

mysql where type int

my table 'users' have a following schema
| id | name | class|
| 0 | John | Primary |
| 1 | Mary | Primary |
I tried this query:
select * from users where id = 'a'
The mysql return all rows from table.
How can I solve this problem?
If id is of type Integer, you have to type it without quotation marks. For example:
select * from users where id = 0;
should return:
| 0 | John | Primary
However, the 'a' in your example is not an Integer, so I am not 100 percent sure where this comes from and if I understood you correctly.