I want to join a bunch of columns from different tables in the same database in mysql. The problem I have, is that not all values are written in the same table.
The concrete example: In one table there is the sid column. Depending on the value in this column the next values I need in this join are located in different tables. If the sid value equals 1 I have to join with table 2 to get the values I want, if the sid value is anything but 1 I have to join with table 3.
I researched a bit into if - else in mysql but all the information I can find is about changing values and how they are displayed under certain conditions.
I want the workflow to change under certain conditions.
No matter which join gets executed, the resulting table has the same amount of columns. I do not actually display any data from table 2 and table 3. The descr column exists in table 4. All the other displayed columns exist in table 1. So there should not be any problems wit the display.
The code looks as follows (inspired by python):
SELECT type, s_type, id, descr
FROM table1
IF sid = 1 THEN
LEFT JOIN table2
ON table1.sid = table2.sid
LEFT JOIN table4
ON table2.sid = table4.id_name
ELSE
LEFT JOIN table3
ON table1.sid = table3.svid
LEFT JOIN table4
ON table3.svid = table4.id_name
END IF;
What is the correct way to get this control flow done in mysql?
IF cannot be used by this in SQL. If I understand the logic, you could do something like this:
SELECT type, s_type, id, table4.descr
FROM table1 LEFT JOIN
table2
ON table1.sid = table2.sid AND table1.sid = 1 LEFT JOIN
table3
ON table1.sid = table3.svid AND table1.side <> 1 LEFT JOIN
table4
ON table4.id_name = COALESCE(table3.svid, table2.sid)
If your tables are large, the COALESCE() might be a performance killer.
Related
I want to create View by selecting all data from multiple tables, but the error I got saying that I have duplicate columns
CREATE VIEW All_Data AS
SELECT *
FROM table1 tb1
INNER JOIN table 2 tb2 ON tb1.ID = tb2.ID
INNER JOIN table 3 tb3 ON tb2.ID = tb3.ID
INNER JOIN table 4 tb4 ON tb3.ID = tb4.ID
INNER JOIN table 5 tb5 ON tb4.ID = tb5.ID
INNER JOIN table 6 tb6 ON o.SpecialID = tb6.ID
INNER JOIN table 7 tb7 ON tb6.ID = tb7.ID
LEFT JOIN table 8 tb8 ON tb7.ID = tb8.ID
However, I am still having the same problem. I want to know is there a faster way to do that instead using alias selecting each column one by one.
DISTINCT won't help as its talking about duplicate columns vs duplicate rows.
Its the * that is causing the columns from all tables, with duplicate column names to be returned. You'll need to replace the * with explicit columns and alias them like below if both are needed.
SELECT p.created_date as product_created_date, order.created_date as order_created date .....
Note using a view isn't a needed pattern. Selects of exactly the right result are normally sufficient. Selects on views can suffer in performance as they are more complicated for MySQL to optimize. They are useful if you need an explicit GRANT on the them for a specific user however.
You need to provide the full list of columns that you want to be part of the view. There is no shortcut.
But yes, to ease your work, If you want the comma separated list of the column names of the table then you can use the following query for each table and put their columns in your select query. You will then just need to alias the columns which have same names.
Select listagg('pd.'|| column_name, ',')
Within group (order by column_id)
From user_tab_columns
Where table_name = 'your_table_name_in_capital';
Note that you need to replace 'pd.' for each table with the table alias in your query.
Im sure Im missing something vital here so any advices are welcome. I have one base table lets call it Content_1 and two additional tables called Content_2 and Content_3. What Im trying to do is get all results from table_2 matching the id from table 1 and to add to this result set all results from table_3 which also match the id coming from table_1. Basically to have an OR condition in the final results - return everything from table 2 matching the id from table 1 OR return everything from table 3 matching the id from table 1. However I see that no results are returned so my guess is that we make the first join and then second join is applied to the result set returned after the first join, not on the initial join.
SELECT * FROM Content_1
JOIN Content_2 ON Content_1.id = Content_2.id
JOIN Content_3 ON Content_1.id = Content_3.id
You probably want UNION instead of joining all 3 tables.
SELECT Col1, Col2
FROM Content_1
JOIN Content_2 ON Content_1.id = Content_2.id
UNION
SELECT Col1, Col2
FROM Content_1
JOIN Content_3 ON Content_1.id = Content_3.id
I am a newbie at MySQL..... I am trying to left join 3 tables one contains some_id,name,count,descr and second one has id,some_id,uni_id and the last one has uni_id,price,added,etc So when i try to join these three tables it says that there's no such field named descr
What could be the best way to join these tables without modifying structure of them?
Assuming the following schema:
table1(some_id, name, count, descr), where some_id is the primary key;
table2(id, some_id, uni_id), where some_id is a foreign key to table1;
table3(uni_id, price, added), where uni_id is a foreign key to table2.
All you need to do is a LEFT OUTER JOIN between the three tables:
SELECT *
FROM table1 t1 LEFT JOIN table2 t2 ON (t1.some_id = t2.some_id)
LEFT JOIN table3 ON (t2.uni_id = t3.uni_id)
References:
Left Outer Join
Join Syntax
It would be ideal if you could post the schema for your tables. Without seeing the query, it sounds like you've made a reference to a field that you may have aliased to the wrong table.
At the most basic level, "descr" doesn't exist as you've tried to reference it, but beyond that, its hard to say without seeing the query itself.
SELECT descr
FROM table1
LEFT JOIN table2 ON table2.some_id = table1.some_id
LEFT JOIN table3 ON table3.uni_id = table2.uni_id
Should do the trick.
I have 3 tables which contain different types of data related to each other. the tables populate via an excel spreadsheet. I have:
table1 table2 table3
item_number item_number item_number
desc desc qty_sold
qty_instock vdf_cost upc
cost status
What I'm trying to do is use a join function to show all the data as they relate to each other, except the problem is that when I run
SELECT *
FROM table1 a
INNER JOIN table2 b
ON a.someColumn = b.otherColumn
INNER JOIN table3 c
ON b.anotherColumn = c.nextColumn
It just puts the tables side by side, If I run
SELECT *
FROM table1 a
INNER JOIN table2 b
USING(item_number)
It works but only joins the item number (i have no idea how to use multiple fields such as description which repeats), and for some reason I can only use the two tables when I try to add a third table (most likely being done completely wrong)
SELECT *
FROM table1 a
INNER JOIN table2 b
INNER JOIN table3 c
USING(item_number)
I just get a syntax error.
Thanks for all the help in advance
UPDATE:
I got it working
SELECT *
FROM master_list a
INNER JOIN bby_report ab USING (item_number, description)
INNER JOIN sales_report b USING (item_number)
Is there a way I can exclude the description from one of the tables and keep it from another one? Turns out the descriptions are not an exact match from one table to a another so it keeps returning zero results.
So to clarify keep description from table1 and leave out description from table2 while being able to JOIN the fields based on item_number
SELECT *
FROM master_list a
INNER JOIN bby_report ab USING (item_number, description)
INNER JOIN sales_report b USING (item_number)
How can we reference the column value from one table as the reference for a join (see example below)?
SELECT t1.*, t2.*, t3.* FROM term_relationships as t1
INNER JOIN modules as t2 ON t2.module_id = t1.object_id
INNER JOIN t2.nextOfKinTable as t3 ON t3.module_id = t2.module_id;
I thought about using the information_schema but it is too much writing to accomplish something that might be easier by just maintaining a reference to the table you want joined to the current join result, only that I don't know how to make them join this way. Please help :(
Edit:
Essentially what we want is to join table1, table2, and table3 only that the name for table3 is a value stored in table2.
The common column in this case is module_id (object_id)
And the unknown table is t2.nextOfKinTable
Try this out
declare #tabName varchar(1000)
set #tabName = (select top 1 ProductName as tabName from products)
declare #query varchar(8000)
set #query = ' select
p.ProductName as '''+#tabName+'''
from Products p'
---print(#query)
exec (#query)
There's no standard way to do this in SQL. Consider if your t2 table contained 1000 rows, and each row has a distinct nextOfKinTable value. That would result explode the query into a 1002 table join. Not pretty. I'm not even aware of any proprietary syntax that would support it in any products I know of.
If the number of distinct column values are small, you can use LEFT JOINs, but each joined table will receive a different alias (example using 3 tables):
SELECT
t1.*, --TODO: List columns
t2.*, --TODO: List columns
COALESCE(t3.ColumnA,t4.ColumnA,t5.ColumnA) as ColumnA,
COALESCE(t3.ColumnB,t4.ColumnB,t5.ColumnB) as ColumnB
FROM
term_relationships as t1
INNER JOIN
modules as t2
ON
t2.module_id = t1.object_id
LEFT JOIN
Table3 as t3
ON
t3.module_id = t2.module_id AND
t2.nextOfKinTable = 'Table3'
LEFT JOIN
Table4 as t4
ON
t4.module_id = t2.module_id AND
t2.nextOfKinTable = 'Table4'
LEFT JOIN
Table5 as t5
ON
t5.module_id = t2.module_id AND
t2.nextOfKinTable = 'Table5'
You might also want to consider whether these separate tables ought actually to be a single table, with additional column(s) to distinguish the rows. This problem is sometimes referred to as attribute splitting. (See Joe Celko's example of Table splitting in an article from 2009)