I am trying to join two tables based on an id and do aggregations in the final result.
Table1
id name val
0 A 10
1 B 20
2 C 10
Table2
id cat price
0 1 10
0 2 20
1 1 10
1 2 10
2 1 10
SELECT t1.*, t2. FROM
Table1 t1
JOIN Table2 t2 ON t1.id = t2.id;
I'd like to join the two tables and in the final result aggregate the matching rows in Table2. Aggregation function is Average. Final result:
id name val price
0 A 10 15
1 B 20 10
2 C 10 10
When using aggregate functions, you must use a GROUP BY clause to inform the DBMS which attributes to aggregate by. It's also good practice to name the result in a way that indicates the aggregation you used.
SELECT t1.id, t1.name, t1.val, avg(t2.price) as avg_price
FROM Table1 t1
JOIN Table2 t2 on t2.id = t1.id
GROUP BY t1.id, t1.name, t1.val
select t1.id, t1.name, t1.val, avg(t2.price) as price
from Table1 as t1
join Table2 as t2
on t1.id = t2.id
group by t1.id, t1.name, t1.val
Related
I want to combine three tables. Of which two multiple columns have to be joined together.
T1
id
name
1
Carl
2
Max
3
Bob
t2
id
t1_id
lastname
function
5
1
Johnsen
Welder
6
2
Clinten
Carpenter
7
3
Brink
Mason
t3
id
t2-id
Function
9
5
Metalworking
10
6
Cabinet maker
11
7
jointer
result
id
name
lastname
Function
1
Carl
Johnsen
Welder
1
Carl
Johnsen
Metalworking
2
Max
Clinten
Carpenter
2
Max
Clinten
Cabinet maker
3
Bob
Brink
Mason
3
Bob
Brink
jointer
my code is
Select t1.id, t1.naam, t2.lastname , t3.Function
From t1
left join t2 on t2.t1-id=t1.[id]
left join t3 on t3.t2-id=t2.[id],
(Select
Function
from t2
union
select
Function
from t3)t
You need a join with subquery for union based on id
Select
t1.id, t1.naam, t2.lastname, t.Function
From
t1
Left Join
t2 On t2.t1 - id = t1.[id]
Left Join
t3 On t3.t2 - id = t2.[id]
Inner Join
(Select id, Function
From t2
Union
Select id, Function
From t3) t On t.id = t1.id
I am thinking of using union all on two separate queries, one on two tables and one on three tables:
select t1.id, t1.name, t2.lastname, t2.function
from t1 join
t2
on t1.id = t2.t1_id
union all
select t1.id, t1.name, t2.lastname, t3.function
from t1 join
t2
on t1.id = t2.t1_id join
t3
on t2.id = t3.t2_id;
Note that no outer joins are needed. I am guessing that this would be better performing than an option with union/union all.
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;
Example:
Table 1:
id name
1 sim
2 sam
3 jas
Table 2
key age
1 10
1 20
2 40
3 10
Table 3:
id rating
2 7
2 6
3 8
3 7
1 9
Now, what I need is
number of rows that were grouped using group by in both the tables i.e table A and table B.
i.e
select t1.id, count(t2.key) as a, count(t3.id) as b
FROM
table1 t1
LEFT JOIN
table2 t2
ON
t1.id = t2.key
LEFT JOIN
table3 t3
ON
t1.id = t3.id
GROUP BY t1.key, t2.id
Result I expect:
id a b
1 2 1
2 1 2
3 1 2
You're getting duplicates because you're creating a cross product between all 3 tables. Use COUNT(DISTINCT) to filter out the duplicates.
select t1.id, count(DISTINCT t2.age) as a, count(DISTINCT t3.rating) as b
FROM table1 t1
LEFT JOIN table2 t2 ON t1.id = t2.key
LEFT JOIN table3 t3 ON t1.id = t3.id
GROUP BY t1.id
Looks like I am not able to understand some of the solutions given here and in other places, so I decided to ask my own question.
I have three tables. Like this:
table1
id name active
123 item1 1
234 item2 0
345 item3 1 <--- not in table2!!
456 item4 1
567 item5 1
table2
id item_id instock variants deliverytimes
1 123 0 S 21days
2 123 1 M 21days
3 123 2 L 21days
4 456 1 white 10days
5 456 0 black 10days
6 234 0 yellow sold
7 456 1 green sold
8 456 0 red sold
9 567 0 big sold
table3
id item_id description
1 123 Cool Shirt
2 234 Collectors Box
3 345 Comicbook
4 456 Basecap OneSize
5 567 Cool-Mug
I tried several attempts from LEFT JOIN to RIGHT JOIN etc. that all ended up with multiple results that are not DISTINCT in the ID of the first table that I need nor they were complete. Means that if table2 does not comntain item of table1 it won't show in the result.
The closest I got is this:
select * from table1 t1
INNER JOIN (
SELECT * FROM table2
where (deliverytimes!='sold' OR instock>0) LIMIT 1 ) t2
ON t1.id=t2.item_id,
table3 t3
where t1.active = '1'
and t1.id = t2.item_id and t3.item_id = t1.id;
In the end I need a list of:
"id, name, description"
result (as I would like it to be)
id name description
123 item1 Cool Shirt
345 item3 Comicbook
456 item4 Basecap OneSize
that does need to meet this requirements:
"item needs to be t1.active=1"
and
"if items has rows in t2 show only if one row equals (instock>0 or deliverytimes!=sold)"
and
"if item has no rows in t2 show as long as t1.active=1"
Last one is the problem. I never get distinct t1.id when I use other than inner join and with inner join I still miss the rows that are not present in t2 but are still active=1.
When starting to write a query think about what data you want to show. In your case you want to show data from table1 and table3, so join these and select from them. The criteria on table2 belong in the WHERE clause.
The criteria on table2 are:
either no entry in t2 exists
or an entry in t2 exists with instock > 0 or deliverytimes != sold
This means one EXISTS clause, one NOT EXISTS clause, both combined with OR.
select t1.id, t1.name, t3.description
from t1
join t3 on t3.item_id = t1.item_id
where t1.active = 1
and
(
not exists
(
select *
from t2
where t2.item_id = t1.item_id
)
or
exists
(
select *
from t2
where t2.item_id = t1.item_id
and (instock > 0 or deliverytimes != 'sold')
)
);
try this
SELECT DISTINCT(t1.id) as ID, t1.name, t3.description
FROM table1 AS t1
JOIN table2 AS t2 ON t2.item_id = t1.id
LEFT JOIN table3 AS t3 ON t1.id = t3.item_id
if you want to filter you result with active = 1 and != soled filter in where clause
SELECT DISTINCT(t1.id) as ID, t1.name, t3.description
FROM table1 AS t1
JOIN table2 AS t2 ON t2.item_id = t1.id
LEFT JOIN table3 AS t3 ON t1.id = t3.item_id
WHERE t1.active = 1 AND t2.deliverytimes != 'sold'
OR
SELECT DISTINCT(t1.id) as ID, t1.name, t3.description
FROM table1 AS t1
JOIN table2 AS t2 ON t2.item_id = t1.id AND t2.deliverytimes != 'sold'
LEFT JOIN table3 AS t3 ON t1.id = t3.item_id
WHERE t1.active = 1
You can try to link table1 with table2 using Left outer join (this will make sure you will get all records from table1). And now link tbale3 as inner join, this will make sure to get all records which are related with table1.
Table1 LEFT OUTER JOIN TABLE2 and Table1 INNER JOIN table3.
Above is my assumption, you can try the above logic.
I have the 2 following tables t1, t2 with values,
t1 t2
1 4
2 2
3 3
Now I want to output
1
4
How can I get this output in select query ?
This will get you each item from t1 that is not present in t2, and each item in t2 that is not present in t1:
select t1.id from t1
left join t2 on t2.id = t1.id
where t2.id is null
union all
select t2.id from t2
left join t1 on t1.id = t2.id
where t1.id is null
(I have assumed that the field name in each table is named id just for the sake of being able to write a query against the tables.)
Another way would be:
select coalesce(t1.id, t2.id)
from t1
full outer join t2 on t2.id = t1.id
where t1.id is null or t2.id is null
Another way. Just COUNT them.
This works if the values are unique per table
SELECT
CombinedValue
FROM
(
SELECT t1 AS CombinedValue FROM t1
UNION ALL
SELECT t2 FROM t2
) foo
GROUP BY
CombinedValue
HAVING
COUNT(*) = 1
If not unique per table
SELECT
CombinedValue
FROM
(
SELECT DISTINCT t1 AS CombinedValue FROM t1
UNION ALL
SELECT DISTINCT t2 FROM t2
) foo
GROUP BY
CombinedValue
HAVING
COUNT(*) = 1
you can use Joins in MySql to proceed and to obtain result.
this will help you
http://www.techrepublic.com/article/sql-basics-query-multiple-tables/1050307