How to union one column only from multiple tables? - mysql

I am finding it hard to frame the question so I will show what I am trying to do.
Table1 (ID, Name, Score)
1 Jane 10
2 Jack 15
3 Jill 12
4 Jane 10
Table2 (ID, Name, Score)
1 John 11
2 Jill 14
3 Jack 16
4 Jake 15
The result I would like is
Result (Name, Table1.Score, Table2.Score)
Jane 20 NULL
Jack 15 16
Jill 12 14
John NULL 11
Jake NULL 15
Can name become the primary key? Note that Jane occurs twice in table 1(could occur in table 2 as well) and I want to sum the score and make the name unique in that given table.

Here's one way to do it with UNION and SUM:
SELECT T.Name, Sum(T.Score), Sum(T2.Score) Score2
FROM (SELECT Name, SUM(Score) score FROM Table1 GROUP BY Name) t
LEFT JOIN (SELECT Name, SUM(Score) score FROM Table2 GROUP BY Name) t2
ON t.Name = t2.Name
GROUP BY T.Name
UNION
SELECT T.Name, Sum(T2.Score), Sum(T.Score) Score2
FROM (SELECT Name, SUM(Score) score FROM Table2 GROUP BY Name) t
LEFT JOIN (SELECT Name, SUM(Score) score FROM Table1 GROUP BY Name) t2
ON t.Name = t2.Name
GROUP BY T.Name
And here is the SQL Fiddle.
Good luck.

try this
select t1.name , sum(t1.score) as score1 ,sum(t2.score2) as score2 from Table1 as t1
left JOIN
(select name , score as score2 from Table2 )t2
on t1.name = t2.name
group by name
union all
select t2.name , sum(t1.score1) as score1, sum(t2.score) as score2 from Table2 as t2
left JOIN
(select name , score as score1 from Table1 )t1
on t2.name = t1.name
where score1 is null
group by name
---- if you want use the order add this "order by name" here in the end
and this will output :
NAME | SCORE1 |SCORE2
Jack | 15 | 16
Jane | 20 |(null)
Jill | 12 | 14
Jake | (null) | 15
John | (null) | 11
HERE SQLFIDDLE DEMO

Well, if MySQL had full outer join, you would use that. Here is an alternative method:
select id, name, MAX(score1) as score1, MAX(score2) as score2
from ((select id, name, score as score1, NULL as score2
from table1
) union all
(select id, name, null as score1, score as score2
from table1
)
) t
group by id, name
The idea is to get all information needed from each table, with the score in different columns, by using the union all and splitting the score into two separate columns.
The final group by brings them together with one row per id.

Try this:
select
name = Table1.name,
sum(Table1.score) as score1,
sum(Table2.Score) as score2
from Table1
full outer join
Table2
ON
Table2.name = Table1.name
where Table1.name is not null
group by table1.name
UNION
select
name = Table2.name,
sum(Table1.score) as score1,
sum(Table2.Score) as score2
from Table1
full outer join
Table2
ON
Table2.name = Table1.name
where Table2.name is not null
group by table2.name
order by score1 desc, score2

Related

Getting values from 2 tables with different conditions for both tables

Table 1
ID
FirstName
LastNmae
city
Group
code
11
john
smith
abc
E
P
21
don
davis
def
E
P
3
vee
miller
ghi
Q
P
6
vee
miller
ghi
Q
P
Table 2
ID
FirstName
LastNmae
city
Status
EmpName
Phone
11
john
smith
abc
U
Company 1
123
21
don
davis
def
P
Company 2
456
3
vee
miller
ghi
C
Company 3
789
4
jim
jones
xyz
P
comapany4
001
I have 2 tables mentioned above. I need an output from both table under these conditions
For table 1 condition is:
Group='E' AND code='P'
For table 2 condition is : Status = 'U' OR Status = 'P'
For output required columns are:
ID, FirstName, LastName, City, EmpName, Phone
I cannot use UNION because number of columns mismatch.
Desired Output:
ID
FirstName
LastNmae
city
EmpName
Phone
11
john
smith
abc
Company 1
123
21
don
davis
def
Company 2
456
4
jim
jones
xyz
comapany4
001
How can i get desired output. With UNION i can't get "EmpName" and "Phone" column. Is there anyway to use JOIN to get desired output.
I think you still need UNION. Try this query:
SELECT ID, FirstName, LastName, city, EmpName, Phone
FROM table2
WHERE Status IN ('U', 'P')
UNION
SELECT t1.ID, t1.FirstName, t1.LastName, t2.city, t2.EmpName, t2.Phone
FROM table1 AS t1
LEFT JOIN table2 AS t2 ON t1.ID = t2.ID
WHERE t1.Group = 'E' AND t1.code = 'P'
;
First, your results are all coming from table2, so this returns the results specified in the question:
select t2.ID, t2.FirstName, t2.LastName, t2.city, t2.EmpName, t2.Phone
from table2 t2
where t2.status in ('U', 'P');
I think you also want a matching condition on table1 (which is not needed for your example). Based on your description:
select t2.ID, t2.FirstName, t2.LastName, t2.city, t2.EmpName, t2.Phone
from table2 t2
where t2.status in ('U', 'P') or
exists (select 1
from table1 t1
where t1.id = t2.id and
t1.Group = 'E' and t1.code = 'P'
);

MySQL Select first entry of GROUP after custom ORDER BY

I'm trying to fetch the first entry of each group after the custom ORDER BY but don't know how to select that first entry of each group. The groups should be ordered by the #team if exist, otherwise other team else NULL.
SELECT t1.*
FROM tbl t1
INNER JOIN tbl2 t2 ON t2.group_id = t1.group
WHERE t2.region = #region
ORDER BY
CASE
WHEN team=#team THEN 1
WHEN team is NOT NULL THEN 2
WHEN team is NULL THEN 3
END
Content of tbl
id group team
1 1 AA
2 1 BB
3 2 AA
4 2 CC
5 3 BB
6 3 NULL
7 4 NULL
Expected result when #team=AA
id group team
1 1 AA
3 2 AA
5 3 BB
7 4 NULL
Expected result when #team=BB
id group team
2 1 BB
3 2 AA
5 3 BB
7 4 NULL
Use your custom ordering logic with ROW_NUMBER:
WITH cte AS (
SELECT t1.*, ROW_NUMBER() OVER (PARTITION BY t1.`group`
ORDER BY CASE WHEN team = #team THEN 1
WHEN team IS NOT NULL THEN 2
ELSE 3 END) rn
FROM tbl t1
INNER JOIN tbl2 t2 ON t2.group_id = t1.`group`
WHERE t2.region = #region
)
SELECT id, `group`, team
FROM cte
WHERE rn = 1;
Side note: Avoid naming your table columns GROUP, as this is a reserved MySQL keyword, and therefore must always be escaped in backticks.

mysql group query by name and order by id and limit by id

I have a table like this
id name amount
1 fish 120
1 meat 230
2 meat 110
2 fish 78
1 salad 50
3 meat 103
3 salad 22
2 salad 34
i want to write a query that will group the names and sum their amount but it should limit to the first two id, thus group items by name and sum each matching name... this should limit it to the first two id. that is id 1 and 2 only. leaving id 3. Note. the ID is a foreign key from another table.
This is what i have tried. but it's not working
select name, sum(amount) from table1 group by amount, id order by id limit 2
this only outputs 2 results after doing the computation
name amount
fish 198
meat 443
I am expecting something like this
name amount
fish 198
meat 340
salad 84
Add the amount of items with id of only 1 and two and group them by name
select name, sum(amount)
from
(SELECT id, name, amount,
CASE WHEN #name=name THEN #rown:=#rown+1 ELSE #rown:=0 END as rn,
#name:=name
FROM table1, (select #rown:=0, #name:='') s
ORDER BY name, id
) sub
where rn<=1
group by name
output
fish 198
meat 340
salad 84
You don't want to limit to total output but you want to limit it before it makes sum so to do that you can use subqueries.
select t1.name, sum(t1.amount)
from table1 t1 join
(select tt1.id
from table1 tt1
group by id
order by id
limit 2
) t2
on t1.id = t2.id
group by t1.name;
Working example link
Result :
name sum(t1.amount)
fish 198
meat 340
salad 84
SELECT name, sum(amount)
FROM table1
WHERE id <= 2
GROUP BY name
ORDER BY name
Remove the LIMIT and only GROUP BY the name
SELECT Name, SUM(amount) AS Amount
FROM table1
GROUP BY name
ORDER BY id
Output
Name Amount
fish 198
meat 443
salad 106
SQL Fiddle: http://sqlfiddle.com/#!9/2a8868/7/0
What are the first two ids? If I assume you mean "globally", then:
select t1.name, sum(t1.amount)
from table1 t1 join
(select tt1.id
from table1 tt1
group by id
order by id
limit 2
) tt1
on t1.id = tt1.id
group by t1.name;
I think you can use something like this:
SELECT B.NAME, SUM(B.AMOUNT) AS AMOUNT
FROM (
SELECT a.* ,
#r:= CASE WHEN #g = a.NAME THEN #r+1 ELSE 1 END consecutive,
#g:= a.NAME g
FROM DISHES a
CROSS JOIN (SELECT #g:='', #r:=1 ) t1
ORDER BY A.NAME, A.id
) B
WHERE B.consecutive<=2
GROUP BY B.NAME;
Output:
NAME AMOUNT
fish 198
meat 340
salad 84

Using a nested query to get details of two tables

TABLE 1 TABLE 2
id name mob id course mark
1 joe 0000 1 English 77
2 john 0000 2 maths 89
I need to show the name of the person from table 1 who has the MAX(grade) in table 2 using a nested query.
SELECT t1.name
FROM t1
WHERE t1.id = t2.id = (
SELECT id
FROM t2
WHERE mark =
(
SELECT MAX(mark)
FROM t2
)
);
Well, this satisfies the brief ;-):
SELECT a.*
FROM table_a a
JOIN (SELECT * FROM table_b) b
ON b.id = a.id
ORDER
BY mark DESC
LIMIT 1;

Counting unique numbers in a column MySQL

I have a query that returns data in the following format:
id | name | number
1 John 12545
1 John 50496
2 Mary 23443
3 Mark 54
3 Mark 5600
3 Mark 50206
I would like to find out the number of distinct ids that appear in the result set. For example, for the result above. I would like to obtain the value 3.
Is there any way to add a column so the result looks like this instead?
count | id | name | number
3 1 John 12545
3 1 John 50496
3 2 Mary 23443
3 3 Mark 54
3 3 Mark 5600
3 3 Mark 50206
My query is:
SELECT * FROM (
SELECT id FROM tableA
WHERE xyz
) as t1
JOIN tableB using (id)
SELECT (SELECT COUNT(DISTINCT id) FROM tableName) totalCount,
id,name,number
FROM tableName
or by using CROSS JOIN
SELECT x.totalCount,
a.id, a.name, a.number
FROM tableName a, (SELECT COUNT(DISTINCT id) totalCount
FROM tableName) x
You should try :
SELECT id,name,number, (SELECT COUNT(DISTINCT name) FROM YourTableName) FROM YourTableName
Good luck
SELECT COUNT(DISTINCT id) would be faster than using column name.
SELECT (SELECT COUNT(DISTINCT id) FROM tableName) as 'count',
id,name,number
FROM tableName
SELECT COUNT(id) AS count , id, name, number
FROM
(
SELECT id
FROM tableA
WHERE xyz
) as t1
JOIN tableB using (id)
GROUP BY id, name, number