(string) LIKE query with join in Mysql - mysql

I am trying to join two different columns inside the tables using the strings which is only partially common between the two columns of two different table.
How do i combine these two tables:
Suppose if i have 2 tables, table1, table2
╔════╦══════════════════════════════════╦══════╗
║ T1 ║ String1 ║ snr ║
╠════╬══════════════════════════════════╬══════╣
║ 1 ║ Jeff Atwood is good but naughty ║ 5636 ║
║ 2 ║ Geoff Dalgas is bully and fat ║ 148 ║
║ 3 ║ Jeff Atwood likes skoda and hate ║ ║
║ ║ ferrari ║ 101 ║
║ 4 ║ Geoff Dalgas is smart but not ║ ║
║ ║ intelligent ║ 959 ║
╚════╩══════════════════════════════════╩══════╝
╔════╦══════════════════════════════════╦══════╗
║ T2 ║ String2 ║ bnr ║
╠════╬══════════════════════════════════╬══════╣
║ 5 ║ Jeff Atwood is good ║ 1323 ║
║ 34║ Geoff Dalgas is bully ║12148 ║
║ 73║ Jeff Atwood likes skoda ║26101 ║
║ 64║ Geoff Dalgas is smart but ║56959 ║
╚════╩══════════════════════════════════╩══════╝
This is what i am trying to acheive
Result:
╔════╦══════════════════════════════════╦══════╦══════╦══════╗
║ T1 ║ String1 ║ snr ║bnr ║T2 ║
╠════╬══════════════════════════════════╬══════╬══════╬══════╣
║ 1 ║ Jeff Atwood is good but naughty ║ 5636 ║1323 ║5 ║
║ 2 ║ Geoff Dalgas is bully and fat ║ 148 ║12148 ║34 ║
║ 3 ║ Jeff Atwood likes skoda and hate ║ ║ ║ ║
║ ║ ferrari ║ 101 ║26101 ║73 ║
║ 4 ║ Geoff Dalgas is smart but not ║ ║ ║ ║
║ ║ intelligent ║ 959 ║56959 ║64 ║
╚════╩══════════════════════════════════╩══════╩══════╩══════╝
The only relationship i see is to compare the string1 and string2 (which is partially equal)
This is my syntax:
SELECT table1.T1, table1.String1, table1.snr, table2.bnr,table2.T2 FROM table1 INNER JOIN table2 WHERE table1.string1 LIKE table2.string2
but i get any error that
There is a chance that you may have found a bug in the SQL parser. Please examine your query closely, and check that the quotes are correct and not mis-matched. Other possible failure causes may be that you are uploading a file with binary outside of a quoted text area. You can also try your query on the MySQL command line interface. The MySQL server error output below, if there is any, may also help you in diagnosing the problem. If you still have problems or if the parser fails where the command line interface succeeds, please reduce your SQL query input to the single query that causes problems, and submit a bug report with the data chunk in the CUT section below:
ERROR: C1 C2 LEN: 56 57 770 STR: etc...

If you don't have any wildcard characters in the LIKE argument, it just does an exact string match. You need to add % wildcards:
SELECT table1.T1, table1.String1, table1.snr, table2.bnr,table2.T2
FROM table1
INNER JOIN table2 ON table1.string1 LIKE CONCAT('%', table2.string2, '%')

Try this:
Select ID, String From (
(SELECT t1, string1 FROM table1)
UNION
(SELECT t2,string2 FROM table2)) order by ID;

Related

How to select multiple rows where a word is distinct by its letter?

The title may be confusing, but so is the solution I am trying to SELECT from a table of 173k words a distinct word list by letter.
I already tried selecting distinct letters, running on a mariadb 10.1.37
SELECT DISTINCT LEFT(word, 1)
For example a SELECT shouldnt contain more than 1 word beginning with an "A".
Example Table (Because it's hard to understand)
╔═══════════╦═════════╗
║ Word ║ Result ║
╠═══════════╣ ---- ║
║ Charlie ║ Ava ║
╠═══════════╣ Bianca ║
║ Caddie ║ Charlie ║
╠═══════════╣ ║
║ Brooklynn ║ ║
╠═══════════╣ ║
║ Ava ║ ║
╠═══════════╣ ║
║ Alexander ║ ║
╠═══════════╣ ║
║ Bianca ║ ║
╚═══════════╩═════════╝
You can use the following solution using a GROUP BY on the first character:
SELECT MIN(word) FROM table_name GROUP BY LEFT(word, 1)
You can use MIN or MAX to get the first or last word on every group.
demo un dbfiddle.uk

Pivoted MySQL table: Can I group groups and avoid results in one row?

I'm having trouble pivoting a table in MySQL. I've been reading trying to accomplish the result I want, and I'm almost there, but I can't see clearly what to do next.
I'm creating a report of a questionnaire. The report states the person who applied the questionare, the one who solved it and the set of questions with the answers given and some more info.
I have already a query that gives the correct info this way for every person:
╔═══════════════╦══════╦══════════════╦═══════════╦════════════╦════════════════╗
║ supervisor ║ zone ║ promoter ║ visit_id ║ question ║ answer ║
╠═══════════════╬══════╬══════════════╬═══════════╬════════════╬════════════════╣
║ EDGAR MONTIEL ║ VM1 ║ MIGUEL LOPEZ ║ 104285 ║ Question A ║ 1 ║
║ EDGAR MONTIEL ║ VM1 ║ MIGUEL LOPEZ ║ 104285 ║ Question B ║ 1 ║
║ EDGAR MONTIEL ║ VM1 ║ MIGUEL LOPEZ ║ 104285 ║ Question C ║ Any given text ║
╚═══════════════╩══════╩══════════════╩═══════════╩════════════╩════════════════╝
Using GROUP_CONCAT and CONCAT as seen in many tutorials, I've managed to pivot the report retrieving the correct info.
In a nutshell, I did it like this:
SELECT
GROUP_CONCAT(DISTINCT
CONCAT('MAX(IF(infoBase.question = \'',question,'\', \'',answer,'\', 0)) AS \'',question,'\'',''), "\n"
) INTO #answers
FROM (many tables)
WHERE (some expresions)
Then I use a prepared statement to get the final result like this:
SET #query :=
CONCAT(
'SELECT
infoBase.supervisor,
infoBase.zone,
infoBase.promoter,
infoBase.visit_id,
',#answers,' FROM (same tables as before) WHERE (same expresions as before)'
);
Then I execute the query:
PREPARE statement FROM #query;
EXECUTE statement;
Whilst I retrieve the info correctly, my result set looks like this:
╔═══════════════╦══════╦══════════════╦═══════════╦════════════╦════════════╦════════════════╦════════════╦════════════╦══════════════════════════════════════════════════════════════════════╦════════════╦════════════╦════════════════════════════╗
║ supervisor ║ zone ║ promoter ║ visit_id ║ Question A ║ Question B ║ Question C ║ Question A ║ Question B ║ Question C ║ Question A ║ Question B ║ Question C ║
╠═══════════════╬══════╬══════════════╬═══════════╬════════════╬════════════╬════════════════╬════════════╬════════════╬══════════════════════════════════════════════════════════════════════╬════════════╬════════════╬════════════════════════════╣
║ EDGAR MONTIEL ║ VM1 ║ MIGUEL LOPEZ ║ 104285 ║ 1 ║ 1 ║ Any given text ║ 3 ║ 3 ║ Including punctuation characters, like comma, admiration ! or dots . ║ 2 ║ 2 ║ Text is fun, text is life! ║
╚═══════════════╩══════╩══════════════╩═══════════╩════════════╩════════════╩════════════════╩════════════╩════════════╩══════════════════════════════════════════════════════════════════════╩════════════╩════════════╩════════════════════════════╝
The info is correct but it's in the same row and the first part about the people is not seen. So I try to group by visit_id that gives unicity, and I get this:
╔═════════════════╦══════╦══════════════╦═══════════╦════════════╦════════════╦════════════════╗
║ supervisor ║ zone ║ promoter ║ visit_id ║ Question A ║ Question B ║ Question C ║
╠═════════════════╬══════╬══════════════╬═══════════╬════════════╬════════════╬════════════════╣
║ EDGAR MONTIEL ║ VM1 ║ MIGUEL LOPEZ ║ 104285 ║ 1 ║ 1 ║ Any given text ║
║ NEYRA OLIVER ║ VDM2 ║ OMAR SOTO ║ 114442 ║ 1 ║ 1 ║ Any given text ║
║ KAYRA RODRIGUEZ ║ GU1 ║ VICTOR SOTO ║ 114197 ║ 1 ║ 1 ║ Any given text ║
╚═════════════════╩══════╩══════════════╩═══════════╩════════════╩════════════╩════════════════╝
Now the first part of the table is correct but the second part about the questions just reflects the results of the first person in every row. I need to get the following in order to succeed:
╔═════════════════╦══════╦══════════════╦═══════════╦════════════╦════════════╦══════════════════════════════════════════════════════════════════════╗
║ supervisor ║ zone ║ promoter ║ visit_id ║ Question A ║ Question B ║ Question C ║
╠═════════════════╬══════╬══════════════╬═══════════╬════════════╬════════════╬══════════════════════════════════════════════════════════════════════╣
║ EDGAR MONTIEL ║ VM1 ║ MIGUEL LOPEZ ║ 104285 ║ 1 ║ 1 ║ Any given text ║
║ NEYRA OLIVER ║ VDM2 ║ OMAR SOTO ║ 114442 ║ 3 ║ 3 ║ Including punctuation characters, like comma, admiration ! or dots . ║
║ KAYRA RODRIGUEZ ║ GU1 ║ VICTOR SOTO ║ 114197 ║ 2 ║ 2 ║ Text is fun, text is life! ║
╚═════════════════╩══════╩══════════════╩═══════════╩════════════╩════════════╩══════════════════════════════════════════════════════════════════════╝
This is an over simplification of the real problem. The whole problem involves tens of questions for differents questionnaires. Say questionnaire 1 has 45 questions, questionnaire 2 has 30 questions, questionare 3 has 80 questions, etc. So I don't even know the exact number of questions as it varies, thus I'm trying to get this dynamically.
How can I get this result? What do I need to group by or what do I need to do?

SQL My Sub Query is Loading Forever

Okay so basically I am trying to run a simple query with a subquery on phpmyadmin using mysql and it won't stop loading after I run it. The query is:
SELECT t.tagValue FROM tags t WHERE t.tagID IN (SELECT ua.tagID FROM user_taggedArtists ua WHERE ua.userID = 2);
I have ran the individual queries on their own without combining them together and they seem to do what I want, but when I mix them into a subquery form phpmyadmin just loads forever, like I am getting an infinite loop or something.
tags table looks like that:
╔═══════╦═════════════╗
║ tagID ║ tagValue ║
╠═══════╬═════════════╣
║ 1 ║ metal ║
║ 2 ║ alternative ║
║ 3 ║ pop ║
╚═══════╩═════════════╝
etc.
user_taggedArtists table looks like this:
╔════════╦══════════╦═══════╦═════╦═══════╦═══════╗
║ userID ║ artistID ║ tagID ║ day ║ month ║ year ║
╠════════╬══════════╬═══════╬═════╬═══════╬═══════╣
║ 2 ║ 52 ║ 1 ║ 1 ║ 4 ║ 2009 ║
║ 2 ║ 52 ║ 1 ║ 1 ║ 4 ║ 2009 ║
║ 2 ║ 52 ║ 1 ║ 1 ║ 4 ║ 2009 ║
╚════════╩══════════╩═══════╩═════╩═══════╩═══════╝
ect.
Not sure what I am doing wrong here and any help would be greatly appreciated.
Thank you!
Hard to say 'zatly, but "IN", generally, is slow. Try a JOIN and WHERE. I'm going to pretend we can join on tagID. You should have indexes on the join column(s). If not anything you do will perform poorly.
SELECT t.tagValue
FROM tags t
INNER JOIN user_taggedArtists ua ON
t.tagID = ua.tagID
WHERE ua.userID = 2

MySQL - Merge rows in table based on multiple criteria

I'd like to merge rows based on multiple criteria, essentially removing duplicates where I get to define what "duplicate" means. Here is an example table:
╔═════╦═══════╦═════╦═══════╗
║ id* ║ name ║ age ║ grade ║
╠═════╬═══════╬═════╬═══════╣
║ 1 ║ John ║ 11 ║ 5 ║
║ 2 ║ John ║ 11 ║ 5 ║
║ 3 ║ John ║ 11 ║ 6 ║
║ 4 ║ Sam ║ 14 ║ 7 ║
║ 5 ║ Sam ║ 14 ║ 7 ║
╚═════╩═══════╩═════╩═══════╝
In my example, let's say I want to merge on name and age but ignore grade. The result should be:
╔═════╦═══════╦═════╦═══════╗
║ id* ║ name ║ age ║ grade ║
╠═════╬═══════╬═════╬═══════╣
║ 1 ║ John ║ 11 ║ 5 ║
║ 3 ║ John ║ 11 ║ 6 ║
║ 4 ║ Sam ║ 14 ║ 7 ║
╚═════╩═══════╩═════╩═══════╝
I don't particularly care if the id column is updated to be incremental, but I suppose that would be nice.
Can I do this in MySQL?
My suggestion, based on my above comment.
SELECT distinct name, age, grade
into tempTable
from theTable
This will ignore the IDs and give you only a distinct dump, and into a new table.
Then you can either drop the old and, and rename the new one. Or truncate the old one, and dump this back in.
You could just delete the duplicates in place like this:
delete test
from test
inner join (
select name, age, grade, min(id) as minid, count(*)
from test
group by name, age, grade
having count(*) > 1
) main on test.id = main.minid;
Example: http://sqlfiddle.com/#!9/f1a38/1

Ordering a table by time and based on the first appearance of an ID

I'm looking to order a log table so that it is grouped by id based on the first appearance of the id. In my example below, I have a table 'test' and I want to group the table by id so that all the ids are together, i.e. list all '623' entries then all '444' entries. I want the '623' entries to come first because the first '623' record came before the first '444' entries.
Input:
╔═══════╦════════════╦═════╗
║ uid ║ time ║ id ║
╠═══════╬════════════╬═════╣
║ 001 ║ 01:45:10 ║ 623 ║
║ 002 ║ 02:45:20 ║ 444 ║
║ 003 ║ 03:45:30 ║ 444 ║
║ 004 ║ 04:45:40 ║ 623 ║
║ 005 ║ 05:45:50 ║ 623 ║
║ 006 ║ 06:45:00 ║ 444 ║
╚═══════╩════════════╩═════╝
Output:
╔═══════╦════════════╦═════╗
║ uid ║ time ║ id ║
╠═══════╬════════════╬═════╣
║ 001 ║ 01:45:10 ║ 623 ║
║ 004 ║ 04:45:40 ║ 623 ║
║ 005 ║ 05:45:50 ║ 623 ║
║ 002 ║ 02:45:20 ║ 444 ║
║ 003 ║ 03:45:30 ║ 444 ║
║ 006 ║ 06:45:00 ║ 444 ║
╚═══════╩════════════╩═════╝
The closest I've come is this:
select time, id from test group by id, time
╔═══════╦════════════╦═════╗
║ uid ║ time ║ id ║
╠═══════╬════════════╬═════╣
║ 002 ║ 02:45:20 ║ 444 ║
║ 003 ║ 03:45:30 ║ 444 ║
║ 006 ║ 06:45:00 ║ 444 ║
║ 001 ║ 01:45:10 ║ 623 ║
║ 004 ║ 04:45:40 ║ 623 ║
║ 005 ║ 05:45:50 ║ 623 ║
╚═══════╩════════════╩═════╝
But this isn't exactly it because it's ordering by the id. I'm not sure what the proper syntax is to have all the '623' entries get listed first because the first '623' record came before the first '444' entry.
Thanks in advance for any help.
Got the answer:
SELECT test.time, test.id FROM
(
(SELECT DISTINCT id FROM test ORDER BY time ASC) as distinct_test
LEFT JOIN
test ON distinct_test.id = test.id
)
That makes sense now that I see it. Thanks everyone for the help.
Here is the code you need to use; I tested it on your data and it worked. It's basically the same as Jason Swett's, except you must use a LEFT OUTER JOIN rather than a RIGHT OUTER JOIN.
SELECT t.id, t.time
FROM (SELECT DISTINCT id
FROM `table`
ORDER BY time ASC) distinct_t
LEFT OUTER JOIN `table` t ON distinct_t.id = t.id;
Something like...
SELECT test.id,
test.time
FROM (SELECT DISTINCT id
FROM test
ORDER BY time ASC) distinct_test
RIGHT JOIN test ON distinct_test.id = test.id
That might not work but it might at least put you on your way.
Hmm?
SELECT time, id FROM test group by id, time order by id desc