Merge 2 different mysql tables - mysql

I have two tables:
Table a:
+----+------+
| id | data |
+----+------+
| 1 | 450 |
| 2 | 500 |
| 3 | 550 |
| 4 | 600 |
| 5 | 650 |
+----+------+
Table b:
+----+------+------+
| id | a_id | note |
+----+------+------+
| 1 | 2 | 25 |
| 2 | 5 | 10 |
+----+------+------+
I need a query that returns a table that consists of every row from table a with the notes from table b. I want 0 filled in where a note isn't available on a row. I want it to look like this:
+----+------+------+
| id | data | note |
+----+------+------+
| 1 | 450 | 0 |
| 2 | 500 | 25 |
| 3 | 550 | 0 |
| 4 | 600 | 0 |
| 5 | 650 | 10 |
+----+------+------+
How do I do that?

select a.id, a.data, coalesce(b.note, 0) as note
from a
left join b on a.id = b.a_id

What are you looking for is called LEFT/RIGHT JOIN. This question will give you more details about what they are.
Assume you have a query like:
SELECT * FROM a LEFT JOIN b ON some_condition;
Then, its output will contain every row from table a, along with data from table b where the condition is met. For rows where the condition is not met, the columns with data from b will contain null.

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;

Filter every column in MySQL

I have a database with three tables right now : equipements and equipements_statistics that contains the statistics of each equipements and finally stats that contains all type of statistics.
To retrieve an equipement on a filter I'm doing this query :
SELECT
*
FROM
`equipement`
INNER JOIN `equipement_stats` ON `equipement_stats`.`id_equipement` = `equipement`.`id_equipement`
INNER JOIN `stats` ON `stats`.`id_stats` = `equipement_stats`.`id_stats`
WHERE
`stats`.`id_stats` IN(1068, 1069)
GROUP BY
`equipement`.`id_equipement`
HAVING
COUNT(DISTINCT stats.id_stats) = 1
LIMIT 10
Tables are like this :
equipement
+---------------+-----------------+
| id_equipement | name_equipement |
+---------------+-----------------+
| 1 | one |
| 2 | two |
| 3 | three |
+---------------+-----------------+`
equipement_stats
+---------------+-----------+---------------+
| id_equipement | id_stats | random_number |
+---------------+-----------+---------------+
| 1 | 2 | 0 |
| 1 | 4 | 0 |
| 1 | 1069 | 1 |
| 1 | 8 | 0 |
| _____________ | _________ | _____________ |
| 2 | 1070 | 2 |
| 2 | 1069 | 3 |
| 2 | 20 | 0 |
| 2 | 40 | 0 |
+---------------+-----------+---------------+
If stats are 1068 or 1069 I must filter them on the column random_number but random_number value can be different for 1070 and 1069. How to look only for a precise id_stats with a precise random_number?
In my case for example, I would like to filter on equipements that has the stats 1070 with random_number 2 and stats 1069 with random_number 3 as the 2nd entry.
Thanks you for helping!
The easiest way to filter tuples is this:
WHERE (equipement_stats.id_stats, equipement_stats.random_number) IN ( (1068,2) , (1069,3) )

inner join showing duplicate rows in output . it is showing data multiple times

Hello I want to show values table1, and values from table2 and show them together in datagridview.
But my output is showing duplicate values, rather than 2 values its showing 4 values with same values again
query = "select receive_bardana.bales,receive_wheat.bags from receive_bardana
inner Join receive_wheat
On receive_bardana.id= receive_wheat.id
where receive_bardana.id ='1'"
My output is:
+-------+------+
| BALES | BAGS |
+-------+------+
| 100 | 1000 |
| 1000 | 1000 |
| 100 | 2000 |
| 1000 | 2000 |
+-------+------+
What I have stored in tables is:
+-----+-------+
| ID | BALES |
+-----+-------+
| 1 | 100 |
| 1 | 1000 |
+-----+-------+
+-----+------+
| ID | BAGS |
+-----+------+
| 1 | 1000 |
| 1 | 2000 |
+-----+------+
ID IS THE RELATIONSHIP BETWEEN TWO TABLES. EG. I HAVE TWO GODOWNS.
ID IS THE ID NO. OF THE GODOWN
1 FOR GODOWN1
AND 2 FOR GODOWN 2
PRIMARY KEY IS THE AUTO INCREMENT VALUE.
What you can do is to add an extra row with ID2
query = "select receive_bardana.bales,receive_wheat.bags from receive_bardana
inner Join receive_wheat
On receive_bardana.id2 = receive_wheat.id2
where receive_bardana.id ='1'"
|ID | ID2 | BALES
| 1 | 1 | 100
| 1 | 2 | 1000
+-----+------+------+
|ID | ID2 | BAGS
| 1 | 1 | 1000
| 1 | 2 | 2000
+-----+------+------+

MySQL Join two queries in same table

mysql> select * from fact_lab;
+---------+--------+-----+
| product | amount | box |
+---------+--------+-----+
| a | 100 | 1 |
| b | 200 | 1 |
| c | 50 | 1 |
| a | 200 | 2 |
| b | 100 | 2 |
| c | 50 | 2 |
| a | 100 | 3 |
| b | 200 | 3 |
| c | 50 | 3 |
+---------+--------+-----+
9 rows in set (0.00 sec)
I am looking for an output where I can see the total sum of amounts for each product that will show a comparison with amounts for box 2. So, the output should be like the below
+---------+--------+-----+
| product | amount | inbox2 |
+---------+--------+-----+
| a | 400 | 200 |
| b | 500 | 100 |
| c | 150 | 50 |
+---------+--------+-----+
How can i get this result in a single query?
You can get what you want with aggregation. The group by is a basic part of the SQL language. If you don't understand it, then you should study up a bit more on the language.
The second part uses condition aggregation. That is, a case statement is the argument to sum():
select fl.product, sum(amount) as amount,
sum(case when box = 2 then amount else 0 end) as inbox2
from fact_lab fl
group by fl.product;

MySQL delete based on single criteria

I'm not sure how to phrase my question and therefore I struggled to find any answer. My data looks something like this:
+------+-------+------------+----+
| id | block | repetition | x |
+------+-------+------------+----+
| 5223 | 1 | 1 | 15 |
| 5223 | 1 | 2 | 17 |
| 5223 | 1 | 3 | 16 |
| 5223 | 2 | 1 | 14 |
| 5223 | 2 | 2 | 15 |
| 6238 | 2 | 1 | 18 |
| 6238 | 2 | 2 | 20 |
| 6238 | 2 | 3 | 20 |
| 6238 | 2 | 4 | 21 |
+------+-------+------------+----+
I would like to query the table to delete the entire block (column) if I detect x < than 15 (just an example). In this example it should delete rows 4 and 5.
delete t1
from your_table t1
inner join
(
select id, block
from your_table
group by id, block
having sum(x < 15) > 0
) t2 on t1.id = t2.id and t1.block = t2.block
You can use a self-join to extract the data you want to delete. When using the same table twice in a query you need to use alias names to distinguish the tables from each other. That is why I used the t1 and t2 alias names.
By joining, the result (that will be deleted) will only be the records that match the inner join.
SQLFiddle demo