SQL Conditional Join Query - mysql

Consider 3 tables :
Table1
id(pkey) text
col1 text
Example (Table1)
id col1
1 value1
2 value2
Table2
id(pkey) text
name text
Example (Table2)
id name
1 name1
2 name2
3 name3
Table3
table1_id text
table2_id text
Example (Table3)
table1_id table2_id
1 1
2 1
2 2
How do you use joins to select entries(unique) from table 1 such that :
Table1.id == Table3.table1_id
Table2.id == Table3.table2_id
All of Table2.name that are linked to that table1 entry exactly match a given set of strings.
Sample expected :
If the given search set is : ['name1', 'name2']; return all entries from table1 linked to ALL the entries from table3 which have name as 'name1' or 'name2'.
In the considered example, sample valid response :
id col1
2 value2

If I understand correctly, you can use group by and having:
select t3.table1_id
from table3 t3 join
table2 t2
on t3.table2_id = t2.id
group by t3.table1_id
having sum( case when t2.name in (?, ?, ?) then 1 else 0 end) = count(*) and
count(*) = 3; -- number of elements
Note: This assumes that table3 has no duplicates, which is normally the case.

Please use below SQL query for your problem , I have tried it at my end it working for me .
SELECT t1.id
,t1.col1
FROM Table1 AS t1
INNER JOIN Table3 AS t3 ON t1.id = t3.table1_id
INNER JOIN Table2 AS t2 ON t2.id = t3.table2_id
WHERE t2.name = t1.col1
Please check snapshot for the result of this query for better understanding.

Related

FETCH not associated field_name from mysql table

i have tables like below,
Table 1 :
ID
FIELD_NAME
1
field_1
2
field_2
3
field_3
Table 2 :
ID
TAG_NAME
1
tag_1
2
tag_2
3
tag_3
4
tag_4
Table 3 :
FIELD_ID
TAG_ID
1
1
1
2
1
3
2
1
3
2
3
3
so table-3 shows :
field1(from table1) connected with all 3 tag id's of table-2
field2(from table1) connected with all tag id=1 of table-2
and
field3(from table1) connected with all tag id=2,3 of table-2
I like to write a MYSQL Query to fetch
for a given tag_name, find all field name which are NOT associated with this
Example :
input = tag_1
output = field_3
Explanation : as field_3 not have any relation with tag_1 id
input = tag_4
output = field_1, field_2, field_3
Explanation : as no field have any relation with tag_4 id
You could check for fields where certain link table entries do not exist...
SELECT
*
FROM
table1
WHERE
NOT EXISTS (
SELECT *
FROM table3
WHERE field_id = table1.id
AND tag_id = (SELECT id FROM table2 WHERE tag_name = 'tag_4')
)
(Please excuse typos, I'm on my phone.)
dbfiddle as borrowed from #nbk : here
You can do it with a CROSS join of table1 to table2 and a LEFT join yo table3 where you return the unmatched rows:
SELECT t2.TAG_NAME, t1.FIELD_NAME
FROM table1 t1 CROSS JOIN table2 t2
LEFT JOIN table3 t3 ON t3.FIELD_ID = t1.ID AND t3.TAG_ID = t2.ID
WHERE t2.TAG_NAME = ? AND t3.FIELD_ID IS NULL
If you want the results as comma separated list you can also group by TAG_NAME and use GROUP_CONCAT():
SELECT t2.TAG_NAME, GROUP_CONCAT(t1.FIELD_NAME) fields
FROM table1 t1 CROSS JOIN table2 t2
LEFT JOIN table3 t3 ON t3.FIELD_ID = t1.ID AND t3.TAG_ID = t2.ID
WHERE t2.TAG_NAME = ? AND t3.FIELD_ID IS NULL
GROUP BY t2.TAG_NAME
Replace ? with the tag that you search for.
See the demo.

How to select the id with max value that in another table

Here are 2 tables.
Table 1
id value
1 3
2 2
3 3
4 1
5 4
6 3
Table 2
id
1
3
4
How do I get the ids that are in Table 2 which have the max value in Table 1?
Output:
id
1
3
I already tried the following to get the max value, but I cannot figure out how to use it in a single query to get the matching rows. Because I think I need to select from the same table I just inner joined.
select max(table1.value)
from table2
inner join table1 on table1.id = table2.id;
Here is one method:
select t2.id
from (select t2.*, rank() over (order by value desc) as seqnum
from table2 t2 join
table1 t1
on t2.id = t1.id
) t
where seqnum = 1;
Or, an alternative that puts all the ids on one row:
select group_concat(t2.id) as ids
from table2 t2 join
table1 t1
on t2.id = t1.id
group by t1.value
order by t1.value desc
limit 1;
You have a couple of options available without using window functions:
You can use a WHERE clause to select only id values that have a value equal to the MAX(value) from your query and an id that is in Table2:
SELECT t1.id
FROM Table1 t1
WHERE value = (
SELECT MAX(t1.value)
FROM Table2 t2
JOIN Table1 t1 ON t1.id = t2.id
)
AND id IN (SELECT id FROM Table2)
You can JOIN your query to Table1 and Table2 again, matching the value in Table1 and the id in Table2:
SELECT t1.id
FROM (
SELECT MAX(t1.value) AS max_value
FROM Table2 t2
JOIN Table1 t1 ON t1.id = t2.id
) t
JOIN Table1 t1 ON t1.value = t.max_value
JOIN Table2 t2 ON t2.id = t1.id
In both cases the output is
id
1
3
Demo on SQLFiddle
Too low to comment but from the SQL statement you gave, you just need to add the tableid in your select parameters.
select table2.id, max(table1.value)
from table2
inner join table1 on table1.id = table2.id;

finding duplicate columns along joining data from another table

I am trying to find duplicates in a table column only if the row is also a child of another table ex:
table 1 columns
id
Type
table 2 columns
id
table1Id
table3Id
Sample Data:
table 1:
id Type
1 aType
2 myType
3 myType
4 aType
5 myType
6 aType
table 2:
id table1Id table3Id
1 1 1
2 2 1
3 4 2
4 5 1
5 6 2
Results I'd like: (rows in table1 with same Type and table3Id)
table1Id table1Type table3Id
2 myType 1
5 myType 1
4 aType 2
6 aType 2
query I tried
select table1.id as table1Id, table1.type as table1Type, table2.table3Id as table3Id
from table1, table2
inner join table1 a on table1.Type = a.Type
where a.id <> table1.id and table1.Type = "myType" and table1.id = table2.table1Id
The above query give me an error "unknown column table1.Type in on clause"
I have no idea if the query is correct, but you are getting the error because of the comma in the from clause. Here is an easy rule: Never use commas in the FROM clause. Always use explicit JOIN syntax.
You can fix your problem directly by using CROSS JOIN:
select table1.id as table1Id, table1.type as table1Type, table2.table3Id as table3Id
from table1 cross join
table2 inner join
table1 a
on table1.Type = a.Type
where a.id <> table1.id and table1.Type = 'myType' and
table1.id = table2.table1Id;
It is better to put the JOIN conditions in an ON clause:
select t1.id as table1Id, t1.type as table1Type, t2.table3Id
from table1 t1 inner join
table2 t2
on t1.id = t2.table1Id inner join
table1 a
on t1.Type = a.Type and a.id <> t1.id
where t1.Type = 'myType' ;
That fixes the syntax error -- which is your question. If this doesn't deliver what you expect, then ask another question with sample data, desired results, and a clearer description of the logic.

SQL INSERT based on null values comparison from 2 other tables

I have two tables for ex:
Table 1
id code
1 a
2 b
3
Table 2
id code
4 a
5 b
6
Table 3
id id1
1 4
2 5
I basically want to insert table 3 with the ids of table 1 and table 2 where based on table1.name = table2.name.
INSERT INTO table3(id,id1)
SELECT t1.id,t2.id FROM table1 t1, table2 t2 where t1.name=t2.name;
However table 1 and table 2 has null codes for 3rd row, how will i compare as null = null wont work.
Help is appreciated..
Just add a (t1.name IS NULL AND t2.name IS NULL) test:
INSERT INTO table3 (id, id1)
SELECT t1.id, t2.id
FROM table1 t1
INNER JOIN table2 t2 ON t1.name = t2.name OR (t1.name IS NULL AND t2.name IS NULL);
As I learned a few days ago, MySQL supports a syntax enhancement <=> to compare NULLs as equal:
INSERT INTO table3(id,id1)
SELECT t1.id,t2.id
FROM table1 t1 JOIN table2 t2
ON t1.name <=> t2.name;
Edit:
MySQL reference
In oracle, using nvl() for convert null value to less-used characters.
INSERT INTO table3(id,id1)
SELECT t1.id,t2.id
FROM table1 t1, table2 t2
WHERE nvl(t1.code,'$$')=nvl(t2.code,'$$');
use inner join
INSERT INTO table3(id,id1) SELECT t1.id, t2.id
FROM table1 t1
INNER JOIN table2 t2 ON t1.name = t2.name OR (t1.name IS NULL AND t2.name IS NULL);

Combining multiple tables

Table1: ID,Name,some more columns
Table2: ID
Table3: Name
I want get output from table1, whose IDs are present in Table2.IDs & whose Name are present in Table3.Name.
In other words, select data which is present in ALL the 3 tables.
For ex:
Table1:
1 John
2 Will
3 Michael
Table2:
1
Table3:
Will
The output should be
1 John
2 Will
You need to use JOINs.
Your description and your sample output do not match, so I'll give you one example for each.
Based on your description, it should be 2 INNER JOINs:
select table1.id, table1.name
from table1
inner join table2 on table2.id = table1.id
inner join table3 on table3.name = table1.name
Based on your output, it should be 2 OUTER JOINS with a WHERE clause specifying that at least one of the 2 joins was satisfied:
select table1.id, table1.name
from table1
left outer join table2 on table2.id = table1.id
left outer join table3 on table3.name = table1.name
where table2.id is not null or table3.name is not null
Based on your expected results, it looks like you want rows from Table1 that match either Table2 OR Table3, so you'll want to use LEFT JOINs.
select t1.ID, t1.Name
from Table1 t1
left join Table2 t2
on t1.ID = t2.ID
left join table3 t3
on t1.Name = t3.Name
where t2.ID is not null
or t3.Name is not null