Generate MQsql query to get records - mysql

I am having the following table say "A"
"column1" "column2"
1 arafath#gmail.com
2 ram#gmail.com;arafath#gmail.com
3 tom#gmail.com
I want to get the records with the following condition.
Condition1:
If the column value exist in the any of the row, it will retrieve the matched rows
Condition2:
If the column value doesn't match with any of the row, it wants to retrieve all the rows
Eg: column2 = "ram#gmail.com"
Output should be "row 2"
Eg: column2 = "arafath#gmail.com"
Output should be "row 1, row 2"
Eg: column2 = "xxx#gmail.com" (Unmatched column)
Output should be all the rows (row 1, row 2, row 3)
Please help me out to solve the problem.
Thanks in advance.

Please try the below one.
SELECT col1, col2
FROM yourTable
where ( not exists (Select col2
FROM yourTable where col2 like 'xxx#gmail.com')
or col2 like 'xxx#gmail.com');

We can try using a union here:
SELECT col1, col2
FROM yourTable
WHERE col2 REGEXP '[[:<:]]ram#gmail.com[[:>:]]'
UNION ALL
SELECT col1, col2
FROM yourTable
WHERE col2 NOT REGEXP '[[:<:]]ram#gmail.com[[:>:]]' AND
NOT EXISTS (SELECT 1 FROM yourTable WHERE col2 REGEXP '[[:<:]]ram#gmail.com[[:>:]]');
Demo
The above strategy is that the first half of the union returns the matching record, if it exists. The second half of the union then returns all other records, but only if on match were found in the first half of the union. If a match were found, then the WHERE clause in the second half of the union would fail, and would return nothing.
Also, please note that storing comma separated (or semicolon separated) data in your MySQL tables is generally bad practice. I had to use REGEXP to get around this problem, but ideally if each email had a separate row, we would only need to use = equality.

Related

Order by first non-null result that comes from two different columns

I want to browse through all values of two columns in a table:
if the value in column 1 is not null, select it, otherwise select the value in column 2 instead.
then sort the final result in alphabetical ascending order, wherever column its values came from.
I tried the following query but it doesn't work and I'm not even sure it is supposed to do what I want to do.
SELECT *
FROM table
ORDER BY (CASE WHEN col1 IS NOT NULL THEN 1 ELSE 2 END ),
col1 DESC,
col2 DESC)
Besides the fact that it doesn't work (nothing outputted), it seems to sort the values of each column separately while I want to sort the final set of values retrieved, regardless of the column they are from.
Thank you for your help.
If you want to fix it with the CASE expression, it'd look like the following:
SELECT *,
CASE WHEN col1 IS NOT NULL
THEN col1
ELSE col2
END AS col
FROM table
ORDER BY col
Although a nice option is using the COALESCE function. It returns the first non-null value in the list of arguments.
SELECT *, COALESCE(col1, col2) AS col
FROM table
ORDER BY col

How to build a sequence of values by combining two columns?

I am looking to get a sequence of values by combining two columns that are linked using some random ids:
Table (col2 and col3 are linked)
col1 col2 col3
aa a144 d653
bb z567 a144
cc d653 h999
dd y678 z567
The two columns (col2 and col3), this is like a chain that is forming up.
The result I am looking for is a sequence from start to end:
sequence
y678
z567
a144
d653
h999
Explanation:
The sequence starts at row 4 (dd,y678,z567), followed by row 2 (bb,z567,a144) and so on.
Col3 id is the reference for the Col2 id, to decide the next element.
What you're looking for is a recursive query.
Assuming your table is called data, you do it like this:
WITH RECURSIVE query(id) AS (
SELECT col2
FROM data
WHERE col1 = 'dd' -- Select the initial row here
UNION ALL
SELECT data.col3
FROM data
INNER JOIN query on query.id = data.col2
)
SELECT *
FROM query;
Tested snippet available here: https://onecompiler.com/mysql/3xvj2a47v.
This syntax works in MySQL version 8 and up. If your version is lower, first thing I would recommend is to update it, if possible. If not possible, consult this answer for a workaround using MySQL 5: https://stackoverflow.com/a/33737203/2979473.
you are going to have to use a cursor..
https://www.mysqltutorial.org/mysql-cursor/
first step will be to select the value from col2 that doesn't exist in col3
then insert the value from col3 where the current variable is in col2
return the results set when the value in col3 is not found in col2
This will only work if there is one start and end value and one distinct path through the chain.
It will also be slow, because this is not how RDBMS databases are designed to work.
I think this query will work for you.
SELECT DISTINCT SEQ
FROM
(
SELECT COL2 SEQ FROM TABLE1
UNION
SELECT COL3 SEQ FROM TABLE1
) ORDER BY 1

MySQL select statement access part of hex value in column

I have a table like so:
Type Col1
0 ff
1 9f
3 92
and I want to access just a part of the col1 values
i.e. I want to query the table with a value such as Col1=92 where all the rows return
and if I queried with Col1=94 then row 0 and 1 would return and if I queried with Col1=12 only row 0 would return. Obviously some operation would need to happen on the above assignment statements for this to work.
so something like this:
SELECT * FROM TABLE1 WHERE Col1(1)=9;except I understand that sintax does not work...
hope this makes sense
You have at least 3 options
first being
where `col1` like '9%'
second
where substr(`col1`,1,1) = "9"
Third
where left(`col1`, 1) = "9"
Assuming that col1 is a text field, you could do:
SELECT * FROM table1 WHERE col1 LIKE '9%';
returns any row where col1 starts with a 9.
See http://dev.mysql.com/doc/refman/5.0/en/pattern-matching.html for more "LIKE" patterns
Alternatively, you could use substr(string, start, length), so it would be:
SELECT * FROM table1 WHERE substr(col1,1,1)='9'

When querying multiple tables using UNION ALL the AS keyword only works for the first table

I have a query:
(SELECT col1 AS table1 FROM table1 WHERE col3 IS NOT NULL)
UNION ALL
(SELECT col1 AS table2 FROM table2 WHERE col3 IS NOT NULL)
UNION ALL
(SELECT col1 AS table3 FROM table3 WHERE col3 IS NOT NULL)
However when I process this using PDO and the fetchAll(PDO::FETCH_ASSOC); command, the keys to the array generated all come out as table1 irrespective of the table they are actually from.
Is my syntax incorrect? Thanks!
Your query returns a single column. A single column can only have one name/alias. In a UNION query, the first subquery defines the resulting set's column names.
If you want to specify which table each value has come from, add another column, e.g. like this:
(SELECT col1, 'table1' AS src FROM table1 WHERE col3 IS NOT NULL)
UNION ALL
(SELECT col1, 'table2' FROM table2 WHERE col3 IS NOT NULL)
UNION ALL
(SELECT col1, 'table3' FROM table3 WHERE col3 IS NOT NULL)
That's the SQL specification: The column names of the result set are taken from the first select.
It's just the way it is.
When you think about it, having different column names in subsequent selects makes no sense, because a column name can't change part way through a result set - column names are defined (once) for the (entire) result set.
Yes, this the way it works, the unioned values will have the alias from the column in the first query. Quoted from UNION documentation page:
The column names from the first SELECT statement are used as the
column names for the results returned.
If you didn't need that, give that column the alias you want.

How to check in mysql that normalized table is ok or not in mysql

MY base table have two colums assume col1,col2.
col1 have id, col2 have many comma seprated values colm1 is primary key.
like
col1 col2
---------------------
123 (22,34,12)
124 (45,67,11)
Now i have another table which is in normalized form of the first one like
col1 col2
---------------
123 22
123 34
123 12
124 45
124 67
Now the question is that i want to check that my second table have exect data of first table or not.
And if not then how to find that error.
( i need to show the extra row of second table and missing row of second table seperately )
Something liket that. But unverified
select col1, col2 from old_table
left outer join (select col1, group_concat(col2 separator ',') as col2
from new_table
group by col1) as new_table
on new_table.col1 = old_table.col1 and new_table.col2 = old_table.col2
Get a cursor or recordset and you will then do a loop of all records from table 1,
rs_col1 = id
rs_col2 = the comma seperated values
for each record in rs
select * from table_2 where id = rs_col1 and table_2.col2 not in (rs_col2)
loop
I think your unnormalized data is not quite useful, as the data is not ordered so you can't use a group_concat. However, you might be able to find a solution by using find_in_set and counting the amount of matches of col2 (normalized table) in col2 (unnormalized table) grouped by col1. You will then have to make sure that amount of matches is equal to the amount of elements in the multivalued cell.
Thanx to everbody for suggestions.
I got my solution through this query
select * table1 as a
join table2 as b
on a.col1=b.col1
where a.col2 not like concat('%',b.col2,'%')