How to join tables and include entries where not in both tables? - mysql

I have two tables like:
Table A
+-----------+---------------+
| AccountID | NumberOfAdams |
+-----------+---------------+
| A1 | 2 |
| A2 | 5 |
| A3 | 10|
+-----------+---------------+
Table B:
+-----------+----------------+
| AccountID | NumberOfBrowns |
+-----------+----------------+
| A3 | 13 |
+-----------+----------------+
Using a LEFT JOIN, with table B as the first table, the resulting table is:
+-----------+---------------+----------------+
| AccountID | NumberOfAdams | NumberOfBrowns |
+-----------+---------------+----------------+
| A3 | 10 | 13 |
+-----------+---------------+----------------+
What I want to get is:
+-----------+---------------+----------------+
| AccountID | NumberOfAdams | NumberOfBrowns |
+-----------+---------------+----------------+
| A1 | 2 | NULL |
| A2 | 5 | NULL |
| A3 | 10 | 13 |
+-----------+---------------+----------------+
How can I retrieve all AccountIDs from both with a JOIN?

This query might work
SELECT p.AccountID, a.NumberOfAdams, b.NumberOfBrowns
FROM (
SELECT AccountID
FROM table_a
UNION
SELECT AccountID
FROM table_b
) p
LEFT JOIN table_a a ON p.AccountID = a.AccountID
LEFT JOIN table_b b ON p.AccountID = b.AccountID

Related

MySQL JOIN two tables on closest matching value

I have the following situation:
tableA
+-------+-------+
| id | Value |
+-------+-------+
| 1 | 1000 |
| 2 | 20 |
| 3 | 62 |
| 4 | 0 |
+-------+-------+
tableB
+-------+--------+
| Value | Lookup |
+-------+--------+
| 10 | a |
| 20 | b |
| 30 | b |
| 40 | g |
| 50 | h |
| 60 | f |
| 70 | a |
| 80 | a |
| 90 | v |
| 100 | b |
+-------+--------+
And I need to return the lookup in table B that most closely matches the value field in table A. For example.
+-------+-------+--------+
| id | Value | Lookup |
+-------+-------+--------+
| 1 | 1000 | b |
| 2 | 20 | b |
| 3 | 62 | f |
| 4 | 0 | a |
+-------+-------+--------+
How can I go about doing this?
Here is an option using joins:
SELECT
a.Id, a.Value, b.Lookup
FROM tableA a
CROSS JOIN tableB b
INNER JOIN
(
SELECT a.Id, MIN(ABS(a.Value - b.Value)) AS min_abs_value
FROM tableA a
CROSS JOIN tableB b
GROUP BY a.Id
) t
ON a.Id = t.Id AND
ABS(a.Value - b.Value) = t.min_abs_value;
Demo
While this query does join to a subquery, the subquery is not correlated.
One way is to use a correlated subquery:
SELECT a.Id, a.Value,
(SELECT b.Lookup
FROM TableB AS b
ORDER BY ABS(a.Value - b.Value) LIMIT 1)
FROM TableA AS a
Demo here

SQL join table with same column name

I want to join two tables with the same column names and update it using by ID (unique key)
With your Example:
select * from Table1;
+----+------+------+--------+
| ID | Name | age | Gender |
+----+------+------+--------+
| 1 | Pars | 23 | M |
| 2 | Pepe | 24 | M |
| 3 | Pio | 25 | M |
| 4 | Pak | 26 | F |
+----+------+------+--------+
select * from Table2;
+------+------+------+--------+
| ID | Name | age | Gender |
+------+------+------+--------+
| 1 | Pars | 30 | M |
| 2 | Pepe | 31 | M |
| 3 | Pio | 32 | M |
+------+------+------+--------+
After the Update Query:
Update Table1 join Table2 using(ID) set Table1.AGE=Table2.AGE;
RESULT:
select * from Table1;
+----+------+------+--------+
| ID | Name | age | Gender |
+----+------+------+--------+
| 1 | Pars | 30 | M |
| 2 | Pepe | 31 | M |
| 3 | Pio | 32 | M |
| 4 | Pak | 26 | F |
+----+------+------+--------+
I think that this may help you.....
The query uses the inner join to join the table1 and table2
SELECT T1.name1,T2.name2
FROM `table1` T1
INNER JOIN `table2` T2 ON t2.name1=t1.PrimaryKey;
Used left join to join the tables.
Try this code:-
select a.id ,
coalesce(a.name,b.name) as name
,coalesce(b.age,a.age)as age
,coalesce(a.gender,a.gender)as gender
from table1 as a
left join Table2 as b
on a.id=b.id
Try this also:
update Table1 set Table1.age=Table2.age from table1 inner join table2 on Table1.id=Table2.id

Mysql count column values and merge columns

I was having problems in creating counting rows by grouping based on a given field value.
For example: I have a Table A structure like this:
+------+------------+
| id | Person |
+------+------------+
| 1 | "Sandy" |
| 2 | "Piper" |
| 3 | "Candy" |
| 4 | "Pendy" |
+------------+------+
Also I have a Table B structure like this:
+------+------------+---------+
| id | Person | Point |
+------+------------+---------+
| 1 | "Sandy" | 10 |
| 2 | "Piper" | 20 |
| 3 | "Candy" | 30 |
| 4 | "Sandy" | 10 |
| 5 | "Piper" | 20 |
| 6 | "Zafar" | 30 |
+------------+------+---------+
And needed a result like:
+------+------------+---------+
| id | Person | Point |
+------+------------+---------+
| 1 | "Piper" | 40 |
| 2 | "Candy" | 30 |
| 3 | "Zafar" | 30 |
| 4 | "Sandy" | 20 |
| 5 | "Pendy" | 0 |
+------------+------+---------+
I hope the table examples are itself self-explanatory.
SELECT person
, SUM(point) total
FROM
( SELECT person,point FROM table_b
UNION
ALL
SELECT person,0 FROM table_a
) x
GROUP
BY person
ORDER
BY total DESC;
It is a simple left join with a group by
select tableA.person, sum(tableB.points) from tableA left join tableB on tableA.person = tableB.person group by tableA.person
union
select tableB.person, sum(tableB.points) from tableB left join tableA on tableA.person = tableB.person where tableA.id is null group by tableA.person
I think below sql useful to you.
select a.id, a.Person,b.total_point from (
select id, Person from tablea) as a join
(select Person, sum(Point) as total_point from tableb group by person) as b on a.person =b.person
Thank you

One to many join but only the first row

I have 2 tables that I need to join via ID without getting the duplicate values For ID, InfoA, and InfoB. I do not need the data in column InfoB2. When I join the table on ID because it is a 1 to many join I end up with duplicate values and want to get rid of those. I only want ID, InfoA, and InfoB without the duplicates. Any ideas?
Example:
TableA:
| ID | InfoA |
| 1 | animals|
| 2 | plants |
TableB:
| ID | InfoB | InfoB2 |
| 1 | A | X |
| 1 | A | Y |
| 1 | A | Z |
| 2 | B | X |
| 2 | B | Y |
| 2 | B | Z |
Doing a normal join, because it is 1 to many I get this but do not want the duplicates. I don't want this:
| ID | InfoB | InfoB |
| 1 | animals| A |
| 1 | animals| A |
| 1 | animals| A |
| 2 | plants | B |
| 2 | plants | B |
| 2 | plants | B |
My goal is to get this (note I do not need column InfoB2):
| ID | InfoA | InfoB |
| 1 | animals| A |
| 2 | plants | B |
You could use the distinct keyword:
SELECT DISTINCT a.id, infoa, infob
FROM tablea a
JOIN tableb b ON a.id = b.id
The fastest way is likely to be:
select a.*,
(select b.infob from tableb b on a.id = b.id limit 1)
from tablea a;
For performance, you would want an index on tableb(id, infob).

How to fetch data from two tables using mysql query with some conditions applied to the second table?

I want to generate a result from a MySql query with below requirement.
Table 1 :
---------------
| nid | type |
---------------
| 1 | forum |
| 2 | forum |
| 3 | forum |
| 4 | forum |
---------------
Table 2
-----------------------
| nid | cid | created |
-----------------------
| 1 | 32 | 123456 |
| 2 | 65 | 123457 |
| 4 | 67 | 123458 |
| 1 | 61 | 123491 |
| 1 | 78 | 123497 |
| 2 | 23 | 123498 |
| 1 | 12 | 123698 |
| 4 | 54 | 132365 |
| 4 | 81 | 135698 |
| 1 | 30 | 168965 |
-----------------------
Now i require result like below. (Condition : I need the nid from first table, smallest cid for the corresponding nid in second table WHERE type = 'forum')
--------------
| nid | cid |
--------------
| 1 | 12 |
| 2 | 23 |
| 4 | 67 |
--------------
You can try this
SELECT tbl1.nid,
min(tbl2.cid) as cid
FROM table1 tbl1
INNER JOIN table2 tbl2 ON tbl1.nid=tbl2.nid
GROUP BY tbl2.nid;
SQL Fiddle
Try this
SELECT t1.nid,
min(t2.cid) as cid
FROM table1 t1
INNER JOIN table2 t2 ON t1.nid=t2.nid
GROUP BY t2.nid;
This could also work
select nid, min(cid) cid
from table2
group by nid
The above queries are have issues in group by clause. Kindly check this query.
SELECT t1.NID, MIN(t2.CID) AS cis from
TAB1 t1 inner join TAB2 t2 on t1.nid = t2.nid
group by t1.nid