how to combine or merge two resultsets in mysql? - mysql

I have two resultsets A and B
The table A looks like this
+------+---------+------------+
| a_id | item no | total sold |
+------+---------+------------+
| 1 | 101 | 23 |
| 2 | 102 | 34 |
| 4 | 405 | 54 |
| 5 | 506 | 65 |
| 6 | 104 | 23 |
+------+---------+------------+
The table B looks like this
+------+---------+----------+
| b_id | item no | location |
+------+---------+----------+
| 1 | 101 | A1 |
| 2 | 102 | A2 |
| 3 | 103 | A3 |
| 4 | 104 | A4 |
+------+---------+----------+
I want to achieve the output as follows
+------+---------+------------+----------+
| a_id | item no | total sold | location |
+------+---------+------------+----------+
| 1 | 101 | 23 | A1 |
| 2 | 102 | 34 | A2 |
| 4 | 405 | 54 | NULL |
| 5 | 506 | 65 | NULL |
| 6 | 104 | 23 | A4 |
+------+---------+------------+----------+
I want to append the column 'LOCATION' to table A and display the location value for each item no which is present in table B. If the ITEM NO in table A does not have a location value, then the LOCATION value has to be NULL (i.e EMPTY).
Since I am a beginner, I don't know how to achieve it. I tried using UNION but I failed to write a proper query

What you are looking for is a Join. Specifically a Left Outer Join so you get all of the results from your Left table (TableA) and only those results from your right table (TableB) that match.
When specifying a join, you use the ON clause to tell the DB which fields are related between the tables:
SELECT
a_id,
a.itemno,
a.totalsold,
b.location
FROM
tableA
LEFT OUTER JOIN tableB ON
tableA.itemno = tableB.itemno

You should use LEFT JOIN (left cause you want to get nulls when the record is not found in the second table)
SELECT a.a_id, a.itemno, a.totalsold, b.location
FROM tableA AS a LEFT JOIN tableB AS b ON
a.itemno = b.itemno

Related

How to update a column with the number of rows that have a matching column pair?

I have a table called related_clues which lists the id's of pairs of clues which are related
| id | clue_id | related_clue_id | relatedness |
+----+---------+-----------------+-------------+
| 1 | 1 | 232 | 1 |
| 2 | 1 | 306 | 1 |
| 3 | 1 | 458 | 1 |
| 4 | 2 | 620 | 1 |
| 5 | 2 | 72 | 1 |
| 6 | 3 | 212 | 1 |
| 7 | 3 | 232 | 1 |
| 8 | 3 | 412 | 1 |
| 9 | 3 | 300 | 1 |
+----+---------+-----------------+-------------+
Eventually after a while we may reach two id's such as:
+--------+---------+-----------------+-------------+
| id | clue_id | related_clue_id | relatedness |
+--------+---------+-----------------+-------------+
| 121267 | 1636 | 38 | 1 |
| 121331 | 1636 | 38 | 1 |
+--------+---------+-----------------+-------------+
So in this case, for two distinct id values, we have the same (clue_id, related_clue_id) pair
In this case I would like the relatedness value to be updated to 2, signalling that there are two examples of this (clue_id, related_clue_id) pair. Like so:
+--------+---------+-----------------+-------------+
| id | clue_id | related_clue_id | relatedness |
+--------+---------+-----------------+-------------+
| 121267 | 1636 | 38 | 2 |
| 121331 | 1636 | 38 | 2 |
+--------+---------+-----------------+-------------+
So essentially I would like to run some SQL that sets the relatedness value to the number of times a (clue_id, related_clue_id) pair appears.
When I have no relatedness column present, and I simply run the SQL:
SELECT id, clue_id, related_clue_id, COUNT(*) AS relatedness
FROM `related_clues`
GROUP BY clue_id, related_clue_id
It gives me the required result, but of course this doesn't store the relatedness column, it simply shows the column if I run this select. So how do I permanently have this relatedness column?
You could use a update with join
Update related_clues a
INNER JOIN (
SELECT clue_id, related_clue_id, COUNT(*) AS relatedness
FROM `related_clues`
group by clue_id, related_clue_id
having count(*) = 2
) t on t.clue_id = a.clue_id
and t.related_clue_id = a.related_clue_id
set a.relatedness = t.relatedness
I would approach this as an update/join but filter out rows that don't need to be updated:
update related_clues rc join
(select clue_id, related_clue_id, COUNT(*) AS cnt
from `related_clues`
group by clue_id, related_clue_id
) t
on t.clue_id = rc.clue_id and
t.related_clue_id = rc.related_clue_id
set rc.relatedness = t.relatedness
where rc.relatedness <> t.relatedness;

Left joins, i need an explanation about a code

i am watching a tutorial. There is a code which i don't understand what is supposed to do.
$sql = 'SELECT p.*,
a.screen_name AS author_name,
c.name AS category_name
FROM
posts p
LEFT JOIN
admin_users a ON p.author_id = a.id
LEFT JOIN
categories c ON p.category_id = c.id
WHERE
p.id = ?';
I read about the left joins but i didn't understand them. Can somebody please explain me the code i shared.
Thanks in advance!
Imagine you have two tables. One that stores the information about the programmers on your website, and the other table that keeps track of their online purchases.
PROGRAMMERS Table
+--------------------------------------------+
| ID | NAME | AGE | ADDRESS | SALARY |
+----+----------+-----+-----------+----------+
| 1 | Desire | 32 | 123 fake s| 3000.00 |
| 2 | Jamin | 25 | 234 fake s| 2500.00 |
| 3 | Jon | 23 | 567 fake s| 2000.00 |
| 4 | Bob | 30 | 789 fake s| 1500.00 |
| 5 | OtherGuy | 31 | 890 fake s| 1000.00 |
| 6 | DudeMan | 32 | 901 fake s| 500.00 |
+--------------------------------------------+
PURCHASES Table
+---------------------------------------------+
| ORDER_ID | PROG_ID | DATE | PRICE |
+-------------+---------+---------------------|
| 1 | 1 | 1-1-2017 | 100 |
| 2 | 2 | 1-2-2017 | 200 |
| 3 | 6 | 1-3-2017 | 300 |
+---------------------------------------------|
You decide you need to make a new table to consolidate this information to a table that contains
certain columns you want.
For example, you figure it would be nice for shipping purposes to have a table
that has the ID, the NAME, the PRICE, and the DATE columns.
Currently, the tables we have don't display all of that in a single table.
If we were to LEFT JOIN these tables, we would end up filling the desired columns
with NULL values where there is no information to join.
SELECT ID, NAME, PRICE, DATE
FROM PROGRAMMERS
LEFT JOIN PURCHASES
ON PROGRAMMERS.ID = PURCHASES.PROG_ID;
Notice that I'm selecting the columns I want from the starting table, then joining the right table
even though there might be missing information.
RESULTING TABLE
+-------------------------------------+
| ID | NAME | PRICE | DATE |
+----+----------+-----------------+---+
| 1 | Desire | 100 | 1-1-2017 |
| 2 | Jamin | 200 | 1-2-2017 |
| 3 | Jon | NULL | NULL |
| 4 | Bob | NULL | NULL |
| 5 | OtherGuy | NULL | NULL |
| 6 | DudeMan | 300 | 1-3-2017 |
+-------------------------------------+
For a visual representation of the difference between SQL JOINs check out
https://www.codeproject.com/Articles/33052/Visual-Representation-of-SQL-Joins .

Select on row in left with one to many relation

I have table obs
+--------+-------+
| obs_id | name |
+--------+-------|
| 101 | mics |
| 102 | jan |
+--------+-------+
I have table monitoring
+--------+--------+---------+
| mon_id | obs_id | code_id |
+--------+--------+---------+
| 1 | 101 | 201 |
| 2 | 101 | 201 |
| 3 | 101 | 202 |
| 4 | 102 | 201 |
| 5 | 102 | 202 |
+--------+--------+---------+
I have table code
+--------+-----------+
|code_id | code_name |
+--------+-----------|
| 201 | node |
| 202 | java |
| 203 | c++ |
+--------+-----------+
Query result
+--------+--------+---------+-----------+
| obs_id | name | code_id | code_name |
+--------+--------+---------+-----------+
| 101 | mics | 201 | node |
| 102 | jan | 201 | node |
+--------+--------+---------+-----------+
Can someone give me a proper mysql query to come up my result.
select A.obs_id, A.name, M.code_id, C.code_name from obs as A
left join monitoring as M on M.obs_id = A.obs_id
left join code as C on C.code_id = M.code_id
The return of my query is more than 2 or it is not what I want as a result.
As per your result ,its look like you want to results for only 'node' .
Then query will be look like below :
CREATE PROCEDURE GETDATA
AS
#CodeId int=0
BEGIN
select DISTINCT A.obs_id, A.name, M.code_id, C.code_name from obs as A
left join monitoring as M on M.obs_id = A.obs_id
left join code as C on C.code_id = M.code_id WHERE c.code_id=#CodeId
END
Now ,you need to only pass codeID into stored Procedure ,it will be return an output based on CodeID . Its look like dynamic .
The above query will give result as you required.
If you want to get distinct data for all code, then just remove where condition.
Thanks .

solve mysql query

Today I have been asked a question by an interviewer that stated
we have three tables named as table A, B, and C.
Those tables are like this
A B C
------------------ -------------------------- ----------------------------
| ID | ProjectID | | ID | LocationID | aID | | ID | points | LocationID |
------------------ -------------------------- ----------------------------
| 1 | 15 | | 1 | 131 | 1 | | 1 | 123333 | 131 |
| 2 | 15 | | 2 | 132 | 1 | | 2 | 123223 | 132 |
| 3 | 15 | | 3 | 133 | 1 | | 3 | 522 | 211 |
| 4 | 12 | | 4 | 134 | 2 | | 4 | 25 | 136 |
------------------ | 5 | 136 | 2 | | 5 | 25 | 133 |
| 6 | 137 | 3 | | 6 | 25 | 134 |
| 7 | 138 | 1 | | 7 | 25 | 135 |
-------------------------- ----------------------------
now he told me to write a query that sums the points of those locations whose project is 15.
First i wrote the query to get ID's from table A like this
SELECT ID from A where projectID = 15
then i pass this result in table b query just like this
SELECT LocationID FROM B WHERE aID IN ( SELECT ID from A where projectID = 15 )
Then i calculate the sum of these locations just like this
SELECT SUM(points) from C where LocationID IN(SELECT LocationID FROM B WHERE aID IN ( SELECT ID from A where projectID = 15))
My Result is fine and query is correct. But he rejected my answer by saying that this nested IN Clause will slow down the whole process as when we have thousands of records.
Then he gave me another chance to review my answer but i couldn't figure it out.
Is there anyway to optimize this or is there some other way to do the same.
Any help? Thanks
Try this it may solve your problem.
Select SUM(C.points) FROM C JOIN B ON C.LocationID = B.LocationID JOIN A ON B.aID = A.ID where A.ProjectID = 15 GROUPBY A.ProjectID
Try with this....i hope it will work
select sum(c.points) as sum_points
from A a,B b,C c where
a.ID=b.aID and
b.LocationID=c.LocationID
and a.projectID=15

Joining 3 tables

First off, sorry if this is a near enough duplicate. I've found this question, which nearly does what I want, but I couldn't wrap my head around how to alter it to my needs.
I've got these 3 tables:
cs_Accounts:
+----+-----------------------------+-------------+
| id | email | username |
+----+-----------------------------+-------------+
| 63 | jamasawaffles#googlil.com | jamwaffles2 |
| 64 | jamwghghhfles#goomail.com | jamwaffles3 |
| 65 | dhenddfggdfgetal-pipdfg.com | dhendu9411 |
| 60 | jwapldfgddfgfffles.co.uk | jamwaffles |
+----+-----------------------------+-------------+
cs_Groups:
+----+-----------+------------+-------------+
| id | low_limit | high_limit | name |
+----+-----------+------------+-------------+
| 1 | 0 | 0 | admin |
| 2 | 1 | 50 | developer |
| 3 | 76 | 100 | reviewer |
| 4 | 51 | 75 | beta tester |
| 5 | 1 | 50 | contributor |
+----+-----------+------------+-------------+
cs_Permissions:
+----+---------+----------+
| id | user_id | group_id |
+----+---------+----------+
| 4 | 60 | 4 |
| 3 | 60 | 1 |
| 5 | 60 | 2 |
| 6 | 62 | 1 |
| 7 | 62 | 3 |
+----+---------+----------+
I've been wrestling with a 3 way join for hours now, and I can't get the results I want. I'm looking for this behaviour: a row will be returned for every user from cs_Accounts where there is a row in cs_Permissions that contains their ID and the ID of a group from cs_Groups, as well as the group with the group_id has a high_lmiit and low_limit in a range I can specify.
Using the data in the tables above, we might end up with something like this:
email username cs_Groups.name
----------------------------------------------------------
jwapldfgddfgfffles.co.uk jamwaffles admin
jwapldfgddfgfffles.co.uk jamwaffles developer
jwapldfgddfgfffles.co.uk jamwaffles beta tester
dhenddfggdfgetal-pipdfg.com dhendu9411 admin
dhenddfggdfgetal-pipdfg.com dhendu9411 reviewer
There is an extra condition, however. This condition is where rows are only selected if the group the user belongs to has a high_limit and low_limit with values I can specify using a WHERE clause. As you can see, the table above only contains users with rows in the permissions table.
This feels a lot like homework but with a name like James I'm always willing to help.
select a.email,a.username,g.name
from cs_Accounts a
inner join cs_Permissions p on p.user_id = a.id
inner join cs_Groups g on g.id = p.Group_id
where g.low_limit > 70
and g.high_limt < 120
This is the query
SELECT ac.email, ac.username, gr.name
FROM cs_Accounts AS ac
LEFT JOIN cs_Permissions AS per ON per.user_id = ac.id
INNER JOIN cs_Groups AS gr ON per.user_id = gr.id
You can add a WHERE clause to this query if you want