Mysql select from two tables where first table field = second table field% - mysql

I have two tables.
table1 has a row id='12345'
table2 has a row where the id = that of table1 with added chars, e.g.,
table2.id = '12345-678qt'
table2 may have more than one id starting with '12345-' with different ending chars.
Yes, there is always a dash after table1's id that could be used in the query.
I need to get some data from both tables, say
SELECT table1.id, table1.field9,
table2.id, table2.fieldZ
FROM table1 and table2
WHERE (
table1.id=table2.id's characters before the dash
OR
table1.field1 = 'abcde'
)
AND table2.dataB='something'
ORDER BY table1.datefield DESC LIMIT 3;
Thank you.

The MySQL translation of:
"table1 and table2 WHERE" is table1 INNER JOIN table 2 ON
"table2.id's characters before the dash" is SUBSTRING_INDEX(table2.id, '-', 1)
The query should look like this:
SELECT table1.id, table1.field9,
table2.id, table2.fieldZ
FROM table1
INNER JOIN table2
ON (table1.id = SUBSTRING(table2.id, '-', 1) OR table1.field1 = 'abcde')
AND table2.dataB = 'something'
ORDER BY table1.datefield DESC
LIMIT 3;
This doesn't grant that your query will work if it's written like this. My fixes will remove the current errors inside your query. For more troubleshooting with a sql fiddle link, please provide tables and I'll be happy to help.
Check the official documentation about the JOIN operation and the SUBSTRING_INDEX function at the corresponding links.

Related

How to use Concat() & Substring in one query?

For question purposes I will use minimal data for my examples.
I have a table called table1 and a column named test that looks like this:
test
5012
I am able to add an extra zero behind before the result of column test using this query:
SELECT CONCAT('0',test) as x from table1
this is the result of the query:
results table: table1
x
05012
Now I have another table called table2 looking like this:
test test2
05012 1
My question is, how do I join the two tables together based on that query above and concat the table1 with column test2 from table2? Making sure the first 4 characters of both columns test from both tables match together?
This is how table 1 should look like:
Afterquery
050121
I am curious why you wouldn't simply use table2?
select concat(t2.test, t2.test2) as afterquery
from table2 t2;
table1 doesn't seem to play a role.
If you want values in table2 filtered by table1, you can use exists:
select concat(t2.test, t2.test2) as afterquery
from table2 t2
where exists (select 1
from table1 t1
where t2.test = concat('0', t1.test)
);
You can express this as a join:
select concat(t2.test, t2.test2) as afterquery
from table2 t2 join
table1 t1
on t2.test = concat('0', t1.test);
This is useful if you want columns from both tables -- but that is not necessary to answer the question. On the other hand, this runs the risk of duplication if there are multiple matches.
I think that this should be the solution. You need to use concat in the join between table1 and table2
SELECT CONCAT('0', table1.test, table2.test2) AS Afterquery
FROM table1
INNER JOIN table2
ON CONCAT('0',table1.test) = table2.test
Slightly different approach with a sub-query:
select concat(concat_test, test2) test_results
from
(select concat('0', test) concat_test from table1) table_alias
join
table2 on substring(concat_test,1,4) = substring(test,1,4);

How to check every field in a table is nt substring of a field in another table

My scheme looks like:
I have two tables: table1, table2
table1 has one field: table1-name of type string.
table2 has one field: table2-name of type string.
I want to return all rows of table1-name that are NOT substring of any table2-name records. I did:
SELECT DISTINCT `table2-name`.`table2`
FROM `table2`, `table1`
WHERE `table2-name`.`table2` NOT IN (SELECT `table1-name` FROM `table1`)
LIMIT 100;
But this returns all table2-name that are not equal to table1-name. What I need is all table2-namethat are not sub-string of table2-name.
Example:
table1-name:aa.abc.com, bb.com, xyz.com
table2-name: abc.com, aaa.com, xyz.com
The query above will return:
abc.com
aaa.com
What I want to return is:
aaa.com
I do not want abc.com to be returned because it is a sub-string of aa.abc.com.
Can you correct my query?
Use NOT EXISTS for such conditions:
select *
from table1 t1
where not exists
(
select *
from table2 t2
where t2.`table2-name` like concat('%', t1.`table1-name`, '%')
);
BTW: You should avoid names like table2-name where you need quotes in order to use them. Use something like table2_name instead.
If table2 is not very big, I wonder how this would perform:
select t1.*
from table1 t1 cross join
(select group_concat(t2.name separator '|') as names
from table2 t2
) t2
where t1.name not regexp t2.names;
Or, equivalently:
select t1.*
from table1 t1 cross join
(select group_concat(t2.name) as names
from table2 t2
) t2
where find_in_set(t1.name, t2.names) = 0;
This assumes that t2.name does not have special characters (for regexp) or commas (for find_in_set()).
To check if something is a substring of something else, you would need to use either 'LIKE' (as shown below) or possibly 'REGEXP_LIKE'.
SELECT DISTINCT table2.*
FROM table2
WHERE NOT EXISTS (SELECT 1 FROM table1 where table1.table1name LIKE CONCAT('%',table2.table2name,'%') > 0)
LIMIT 100;
On another note
1 - your problem description is not consistent (you confuse table1 and table2 repeatedly), choosing a better name would likely help with that.
2 - as you will see, I've taken the liberty of renaming the columns to drop the '-' character.
Another version that will work:
SELECT DISTINCT table2.*
FROM table2
WHERE table2name NOT IN (SELECT table2.table2name FROM table1 where table1.table1name like CONCAT('%',table2.table2name,'%') > 0)
LIMIT 100;
Please check the SQLFiddle (I also copied Thorsten Kettner's version above in there after renaming tables/columns)

Inner Join SQL Syntax

I've never done an inner join SQL statement before, so I don't even know if this is the right thing to use, but here's my situation.
Table 1 Columns: id, course_id, unit, lesson
Table 2 Columns: id, course_id
Ultimately, I want to count the number of id's in each unit in Table 1 that are also in Table 2.
So, even though it doesn't work, maybe something like....
$sql = "SELECT table1.unit, COUNT( id ) as count, table2.id, FROM table1, table2, WHERE course_id=$im_course_id GROUP BY unit";
I'm sure the syntax of what I'm wanting to do is a complete fail. Any ideas on fixing it?
SELECT unit, COUNT( t1.id ) as count
FROM table1 as t1 inner JOIN table2 as t2
ON t1.id = t2.id
GROUP BY unit
hope this helps.
If I understand what you want (maybe you could post an example input and output?):
SELECT unit, COUNT( id ) as count
FROM table1 as t1 JOIN table2 as t2
ON t1.id = t2.id
GROUP BY unit
Okay, so there are a few things going on here. First off, commas as joins are deprecated so they may not even be supported (depending on what you are using). You should probably switch to explicitly writing inner join
Now, whenever you have any sort of join, you also need on. You need to tell sql how it should match these two tables up. The on should come right after the join, like this:
Select *
From table1 inner join table2
on table1.id = table2.id
and table1.name = table2.name
You can join on as many things as you need by using and. This means that if the primary key of one table is several columns, you can easily create a one-to-one match between tables.
Lastly, you may be having issues because of other general syntax errors in your query. A comma is used to separate different pieces of information. So in your query,
SELECT table1.unit, COUNT( id ) as count, table2.id, FROM ...
The comma at the end of the select shouldn't be there. Instead this should read
SELECT table1.unit, COUNT( id ) as count, table2.id FROM ...
This is subtle, but the sql query cannot run with the extra comma.
Another issue is with the COUNT( id ) that you have. Sql doesn't know which id to count since table1 and table2 both have ids. So, you should use either count(table1.id) or count(table2.id)

Select both ID columns when using UNION and GROUP BY

I'm desperate with this query. I have two tables table1 and table2, tables are identical but they have different data. I'm trying to remove duplicities by columns code and manufacturer. To do that I need in final result ID from table1 ID from table2 and also columns code and manufacturer
SELECT * FROM (
SELECT id,code,manufacturer FROM table1 WHERE manufacturer = 1
UNION SELECT id,code,manufacturer FROM table2 WHERE manufacturer = 1
) AS t GROUP BY code HAVING COUNT(*) > 1
But in result i got only values from table1. It's OK but I just need to get there id from table2 too. Please can anyone give me some tips how to do this ?
You have two basic problems:
Problem 1:
You are using UNION when you should be using UNION ALL, because UNION removes duplicates!
Problem 2:
This isn't the right way to go about the problem. You should be using a simple join, not a union.
Try this:
SELECT
t1.id as table1_id,
t2.id as table2_id,
t1.code,
t1.manufacturer
FROM table1 t1
JOIN table2 t2
ON t2.code = t1.code
AND t2.manufacturer = t1.manufacturer
WHERE manufacturer = 1 -- this WHERE clause is optional
Your use of the WHERE clause is a little odd - consider removing it to get all duplicates from all manufacturers.

MySQL subqueries weird behavior

I was making a query for search but the result should be obtained from three tables and it works fine for only two characters after that it returns empty rows so can anyone help please
here is my query
SELECT *
FROM tables
WHERE table2_id
IN (
SELECT id
FROM table2
WHERE table3_id
IN (
SELECT id
FROM table3
WHERE name LIKE '%in%'
)
OR
)
name LIKE 'in%'
AND id <> '8'
Any suggestions if I am making the right things and what went wrong when its more than two characters
That's a completely ridiculous query! Use a join - that's what it's for!
SELECT tables.*
FROM tables JOIN table2 ON tables.table2_id = table2.id
JOIN table3 ON table2.table3_id = table3.id
WHERE (name LIKE '%in%' OR name LIKE 'in%' AND id <> 8