Generic query for MySQL and PGSQL - mysql

I want to create a generic query which work with MySQL and PostgreSQL.
For this query, I need to select all column in 3 tables but the result need to have a distinct clause on the ID to eliminate duplicates rows.
Actually in the database, there is 6 records but just 3 are differents:
One of them appears 3 times, an other appears 2 and the last just on.
Records which appears many time are exactly the same and I just want keep one of each.
This is a picture of the 6 records:
And me I want that:
Here is the MySQL Query:
SELECT
*
FROM
table_1
INNER JOIN table_2
ON table_1.id = table_2.table_1_id
INNER JOIN table_3
ON table_2.table_3_id = table_3.id
WHERE
table_3.type = 'foo'
GROUP BY
table_1.id
And this is the PostgreSQL query:
SELECT DISTINCT ON (table_1.id)
*
FROM
table_1
INNER JOIN table_2
ON table_1.id = table_2.table_1.id
INNER JOIN table_3
ON table_2.table_3_id = table_3.id
WHERE
table_3.type = 'foo'
I don't find how to create just one query which work with MySQL and PostgreSQL

Try to first get the distinct ids of the first table, then join the rest on to them.
Though, you will still get somewhat random values for table_1 I guess, if there are multiples ids with different values to them and you not specifying which you want.
SELECT
table_1.*, table_2.*, table_3.*
FROM
(SELECT table_1.id FROM table_1 GROUP BY table_1.id) AS distinctIds
INNER JOIN table_1 ON table_1.id = distinctIds.id
INNER JOIN table_2 ON distinctIds.id = table_2.table_1_id
INNER JOIN table_3 ON table_2.table_3_id = table_3.id
WHERE
table_3.type = "foo"

Related

MySql - select from main table with a lot of connected tables

I have a main table, which is related to 10 other tables through one-to-many relationships.
For example:
main Table table1 table2
---------- ------- -------
id * id* id*
name mainTableId ** mainTableId **
column1 column2
I have tried:
SELECT *
FROM main_table
LEFT OUTER JOIN table1 On table1.mainTableId = main_table.id
LEFT OUTER JOIN table2 On table2.mainTableId = main_table.id
...
The problem is that I am getting a lot of results back, since each result in main_table is being multiplied by all the results in table1, table2, etc.
I would like to use only one SELECT query, since querying the database 10 times takes a long time.
Retrieving 100 results from each table is good enough for my needs, but trying to do the following resulted in an error that limit is not supported with a sub query:
LEFT OUTER JOIN table1 WHERE id in (
SELECT id FROM table1 WHERE mainTableId = mainTable.id LIMIT 100
)
I am using AWS Aurora. How can I improve this query?
SELECT *
FROM main_table
LEFT OUTER JOIN table1 ON main_table.id = table1.mainTableId
LEFT OUTER JOIN table2 ON main_table.id = table2.mainTableId
...
For the second question you could just fetch 100 rows from the other tables and join them instead!
SELECT *
FROM main_table
LEFT OUTER JOIN (SELECT * FROM table1 LIMIT 100)a ON main_table.id = a.mainTableId
LEFT OUTER JOIN (SELECT * FROM table2 LIMIT 100)b ON main_table.id = b.mainTableId
...

3 Table Inner Join Query in MySQL

How would I go about writing a query in MySQL on 3 different tables? Here's what I have so far:
SELECT distinct cool_id, example, table1.name
FROM tardis
INNER JOIN table1
ON table1.unique_id = table2.unique_id
AND table1.unique_id='12345'
AND table2.status='active'
Now let's say that there is a column called 'planets' that exists in a 3rd table. How would I add that to this query to select 'planets' in addition to matching the other conditions in my current query? Also, please advise if an INNER JOIN is not the best choice for this.
Just add another INNER JOIN clause:
SELECT columns
FROM table1
INNER JOIN table2 ON table1.col1 = table2.col2
INNER JOIN table3 ON table1.somecol = table3.othercol
The ON condition in the second join can refer to columns from table1, table2, or both.

3 tables and 2 left joins

Query 1:
SELECT sum(total_revenue_usd)
FROM table1 c
WHERE c.irt1_search_campaign_id IN (
SELECT assign_id
FROM table2 ga
LEFT JOIN table3 d
ON d.campaign_id = ga.assign_id
)
Query 2:
SELECT sum(total_revenue_usd)
FROM table1 c
LEFT JOIN table2 ga
ON c.irt1_search_campaign_id = ga.assign_id
LEFT JOIN table3 d
ON d.campaign_id = ga.assign_id
Query 1 gives me the correct result where as I need it in the second style without using 'in'. However Query 2 doesn't give the same result.
How can I change the first query without using 'in' ?
The reason being is that the small query is part of a much larger query, there are other conditions that won't work with 'in'
You could try something along the lines of
SELECT sum(total_revenue_usd)
FROM table1 c
JOIN
(
SELECT DISTINCT ga.assign_id
FROM table2 ga
JOIN table3 d
ON d.campaign_id = ga.assign_id
) x
ON c.irt1_search_campaign_id = x.assign_id
The queries do very different things:
The first query sums the total_revenue_usd from table1 where irt1_search_campaign_id exists in table2 as assign_id. (The outer join to table3 is absolutely unnecessary, by the way, because it doesn't change wether a table2.assign_id exists or not.) As you look for existence in table2, you can of course replace IN with EXISTS.
The second query gets you combinations of table1, table2 and table3. So, in case there are two records in table2 for an entry in table1 and three records in table3 for each of the two table2 records, you will get six records for the one table1 record. Thus you sum its total_revenue_usd sixfold. This is not what you want. Don't join table1 with the other tables.
EDIT: Here is the query using an exists clause. As mentioned, outer joining table3 doesn't alter the results.
Select sum(total_revenue_usd)
from table1 c
where exists
(
select *
from table2 ga
-- left join table3 d on d.campaign_id = ga.assign_id
where ga.assign_id = c.irt1_search_campaign_id
);

MySQL - Join two tables, different columns in table 1 on the same column in table 2

I'm trying to join a different column (part_type_n (where n ranges from 1 to 54)) on Table1 with the same column (id, primary, autoinc) on Table2.
Schema:
Table1
==============
part_type_1
.
.
.
part_type_54
Table2
=============
id
I tried the obvious query (php generated, looping through n from 1 to 54), omitted repetitive stuff in ...:
SELECT * FROM Table1 JOIN Table2 on (Table1.part_type_1=Table2.id), ..., (Table1.part_type_54=Table2.id)
I receive this error:
1066 - Not unique table/alias: 'Table2'
How do I join these two tables?
You will have to join the table on it self again multiple times.
SELECT * FROM table1 t1
INNER JOIN table2 t2 on t2.Id=t1.part_type_1
INNER JOIN table2 t3 on t3.id = t1.part_type_54;
Hope this helps!
As an alternative to writing a query with 54 table aliases, you could consider joining to the table once - like so:
select ...
from Table1 t1
join Table2 t2
on t2.id in (t1.part_type_1, t1.part_type_2, ... t1.part_type_54)
It worked for me to get my required result as one row of which matches various categories all stored in one table column.
Query
SELECT cm3.*, xp.post_title,GROUP_CONCAT(DISTINCT sc.name) AS cate_list
FROM `xld_posts` xp
JOIN course_map cm0 ON cm0.course_id = xp.ID
JOIN course_map cm1 ON cm1.course_id = cm0.course_id AND cm0.id = 3
JOIN course_map cm2 ON cm2.course_id = cm1.course_id AND cm1.id = 6
JOIN course_map cm3 ON cm3.course_id = cm2.course_id AND cm2.id = 11
JOIN subject_category sc ON cm3.id = sc.id
GROUP by post_title ORDER BY post_title
Note: the categories values 3, 6, and 7 are got from form sumbit. Thus if your form has more than three or less your query should dynamically created and join each table with previous table.
:) Happy if any one felt useful.

SQL Join 2 tables with IDs in one row

I'm trying to join data from two tables into 1 row but i can't seem to figure out how to achieve this.
Table 1 structure
id, name, number, email
Table 2 structure
id, friends
The thing is in table 1, id is unique, whereas in table 2 id is not, he can have many friends. (Ofc this is all example).
I'm trying to get a row looking like this
id, name, number, email, friend[1], friend[2] etc.
Any ideas how i can achieve this, or if i need to change my db structure to be able to get this result?
*Note (he only has a choice of 8 different friends).
The most efficient way would be to group your results together with a JOIN statement;
SELECT T1.*, F1.Friend
FROM Table_1 as T1
LEFT JOIN Table_2 as F1
ON T1.id = F1.id
Then iterate through each of the rows in your mysql client.
Another way to do this is with multiple joins to the same table, but without a better way to distinguish the individual friend records you end up doing some messy exclusions in your JOIN statements.
SELECT T1.*, F1.Friend, F2.Friend, F3.Friend, [snip/] F8.Friend
FROM Table_1 as T1
LEFT JOIN Table_2 as F1
ON T1.id = F1.id AND F1.Friend NOT IN (F2.Friend, F3.Friend, [snip/] F8.Friend)
LEFT JOIN Table_2 as F2
ON T1.id = F2.id AND F2.Friend NOT IN (F1.Friend, F3.Friend, [snip/] F8.Friend)
LEFT JOIN Table_2 as F3
ON T1.id = F3.id AND F3.Friend NOT IN (F1.Friend, F2.Friend, F4.Friend, [snip/] F8.Friend)
[big snip/]
LEFT JOIN Table_2 as F8
ON T1.id = F8.id AND F8.Friend NOT IN (F1.Friend, F2.Friend, [snip/] F7.Friend)
Have you considered implementing group_concat? (http://www.mysqlperformanceblog.com/2006/09/04/group_concat-useful-group-by-extension/)
Regardless of the fact that there would only be 8 friends per user, it isn't practical/efficient solution to generate columns based on joined rows.