Mysql join producing huge result table for small solution set - mysql

I have two tables where I'm trying to select rows where a common field between those tables matches exactly, however it's proving difficult to write the query. Here is a simplified version:
The tables look like this (simplified):
T1:
id, name, sn
T2:
id, location, sn
I'm trying to get t1.name and t2.loc together only where t1.sn=t2.sn. The sn field is unique in both, and so at the most, only 1 record will match between tables. In t1, all records have a sn field value, however in t2 about 30% of them have NULL for sn. So, I an expecting the join to produce somewhat fewer rows than t1 has.
How would I do the join?
Thanks.
Sample data:
t1:
+---+--------+-------+-----+
| id| name | sn | ... |
+---+--------+-------+-----+
| 1 | thing1 | 12345 | |
| 2 | thing2 | 10000 | |
| 3 | thing3 | 33445 | |
| 4 | thing4 | 99223 | |
+---+--------+-------+-----+
T2:
+----+--------+-------+-----+
| id | loc | sn | ... |
+----+--------+-------+-----+
| 90 | here | 12345 | |
| 92 | there | NULL | |
| 96 | near | 33445 | |
| 99 | far | 99223 | |
+----+--------+-------+-----+
Result:
+--------+-------+-------+
| name | loc | sn |
+--------+-------+-------+
| thing1 | here | 12345 |
| thing3 | near | 33445 |
| thing4 | far | 99223 |
+--------+-------+-------+

SELECT
t1.name AS name,
t2.loc AS loc,
t1.sn AS sn
FROM t1
INNER JOIN t2 ON t1.sn=t2.sn

Related

MySql get Count, Value from 3rd Table with reference from 1st table

i would like to get the Count value from the 3rd table... 1st table has reference id to 2nd table, 2nd table has reference id of 3rd table... in 3rd table has the value... that i need to count...
Table struct:
table1: tbl_rack
+------------+---------+--------+
| rack_id | site_id | status |
+------------+---------+--------+
| R-642 | ST5 | Y |
| R-307 | ST6 | Y |
| R-57 | ST7 | Y |
| 390/6 | ST8 | Y |
| 9706 | ST11 | Y |
table2: tbl_site
+---------+-------------+-----------+
| site_id | customer_id | region_id |
+---------+-------------+-----------+
| ST5 | CM8 | RM4 |
| ST6 | CM8 | RM8 |
| ST7 | CM10 | RM2 |
| ST8 | CM11 | RM12 |
| ST11 | CM8 | RM10 |
table3: tbl_customer
+-------------+----------------------+---------------+
| customer_id | customer_name | customer_type |
+-------------+----------------------+---------------+
| CM8 | LIVI-IN | MODERATE |
| CM10 | PEPE | HIGH |
| CM11 | SANDER | LOW |
| CM12 | TOASTER | MODERATE |
I want to count each customers contains how many Racks where ranks status is 'Y'
expected Result1:
Customer No.of Racks
LIVI-IN 3
OTHERS 2
expected Result2:
Customer Type No.of Racks
Moderate 3
High 1
Low 1
Please, follow below SQL query:
select C.customer_name as 'Customer', count(*) as 'No.of Racks'
from tbl_customer C
left outer join tbl_site TS on TS.customer_id = C.customer_id
left outer join tbl_rack TR on TR.site_id = TS.site_id
group by C.customer_name
order by C.customer_name

Concatenating all matches from a join table into a column

I have two MySQL tables (table_a and table_b) and a join table (table_c).
Table Structures:
table_a:
__________________
| table_a: |
|----------------|
| id |
| result_column |
------------------
table_b:
__________________
| table_b: |
|----------------|
| id |
| name |
------------------
table_c:
__________________
| table_c: |
|----------------|
| id |
| table_a_id |
| table_b_id |
------------------
My Goal:
I want to find a query that will:
Iterate over every table_a record and get the table_a.id value
Find any records in table_c which have a matching table_c.table_a_id value
For each matching record in table_c get the table_c.table_b_id value
Find the record in table_b which has a matching table_b.id value
For that matching record in table_b get the table_b.name value
In table_a, concatenate each matched name value into the corresponding table_a.result_column
Example:
Before the Query:
_______________________ _________________________________ ________________
| table_a: | | table_c: | | table_b: |
|---------------------| |-------------------------------| |--------------|
| id | result_column | | id | table_a_id | table_b_id | | id | name |
|-----|---------------| |-----|------------|------------| |-----|--------|
| 1 | | | 1 | 1 | 3 | | 1 | Kevin |
| 2 | | | 2 | 1 | 4 | | 2 | Jesse |
| 3 | | | 3 | 2 | 2 | | 3 | Karen |
----------------------- | 4 | 3 | 1 | | 4 | Tim |
| 5 | 3 | 5 | | 5 | Lauren |
--------------------------------- ----------------
After the Query:
_______________________ _________________________________ ________________
| table_a: | | table_c: | | table_b: |
|---------------------| |-------------------------------| |--------------|
| id | result_column | | id | table_a_id | table_b_id | | id | name |
|-----|---------------| |-----|------------|------------| |-----|--------|
| 1 | Karen, Tim | | 1 | 1 | 3 | | 1 | Kevin |
| 2 | Jesse | | 2 | 1 | 4 | | 2 | Jesse |
| 3 | Kevin, Lauren | | 3 | 2 | 2 | | 3 | Karen |
----------------------- | 4 | 3 | 1 | | 4 | Tim |
| 5 | 3 | 5 | | 5 | Lauren |
--------------------------------- ----------------
For absolute clarity, I understand that this is incredibly bad practice within a relational data-table. This is as far from normalization as one can get. I would never design a database like this. I was tasked with creating a custom column with a list of values purely for a business case.
The query you seem to want is:
select c.table_a_id, group_concat(b.name separator ', ')
from c join
b
on c.table_b_id = b.id
group by c.table_a_id;
If you actually want to update a, you can put this into an update statement:
update a join
(select c.table_a_id, group_concat(b.name separator ', ') as names
from c join
b
on c.table_b_id = b.id
group by c.table_a_id
) cb
on cb.table_a_id = a.id
set result_column = cb.names
Previous answer is close; but you also required that you only want the records matched in table C that are in A.
The first query does not meet this requirement; but the update statement does, as it will only update records in table A, if the id matches the table_a_id value pulled from table C.
Given what you said you wished for the end result, the update statement above would work.
If you wish to be explicit in your logic, just add a join from table A to table C.
select a.id, group_concat(b.name separator ', ')
from a
join c ON (a.id = c.table_a_id)
join b ON (c.table_b_id = b.id)
group by a.id;

combine information from two tables into one table

I need to combine information from two tables into one table, the following table is
table 1
+----+---------------+---------+
|id_k| name | value |
+----+---------------+---------+
| 1 | enak | 4 |
| 2 | nor | 3 |
+----+---------------+---------+
table 2
+------+------+---------+
| id_d | id_k | feel |
+------+------+---------+
| 1 | 1 | good |
| 2 | 1 | better |
| 3 | 1 | verygood|
+------+------+---------+
result should be
+------+------+-------+------------------------+
| id_d | name | value | feel |
+------+------+-------+------------------------+
| 1 | enak | 4 | good, better, verygood |
| 2 | nor | 3 | |
+------+------+-------+------------------------+
this is my code [not worked]
select k.name, k.value, s.feel
from table1 as k
left join table2 as s on s.id_k=k.id_k
http://sqlfiddle.com/#!9/3a7564/1
SELECT t1.id_k,
t1.`name`,
t1.`value`,
GROUP_CONCAT(t2.feel) AS feel
FROM table1 t1
LEFT JOIN table2 t2
ON t1.id_k = t2.id_k
GROUP BY t1.id_k
You could use the gorup_concat function to concatinate the values from table2 to a coma-delimited string in the result:
SELECT table1.id_k, name, value, GROUP_CONCAT(feel SEPARATOR ', ') AS feel
FROM table1
JOIN table2 ON table1.id_k = table2.id_k
GROUP BY table1.id_k

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

How do I properly format this MySQL JOIN Statement?

I've got a table that looks like:
Table 1 ->
+----+--------+--------+
| id | name | author |
+----+--------+--------+
| 1 | First | Me |
| 2 | Second | You |
+----+--------+--------+
Table 2 ->
+-----+------------+-----------+------------+
| mid | table1_id | key | value |
+-----+------------+-----------+------------+
| 1 | 1 | desc | hello |
| 2 | 1 | begin_day | monday |
| 3 | 1 | end_day | tuesday |
| 4 | 2 | desc | goodbye |
| 5 | 2 | begin_day | wednesday |
| 6 | 2 | end_day | friday |
+-----+------------+-----------+------------+
The relationship here is that the id in table 1 corresponds to the table1_id in table 2.
The output that I'm trying to get is...
+----+---------+---------+-------------+-----------+-----------+
| id | name | author | desc | begin_day | end_day |
+----+---------+---------+-------------+-----------+-----------+
| 1 | First | Me | hello | monday | tuesday |
| 1 | Second | You | goodbye | wednesday | friday |
+----+---------+---------+-------------+-----------+-----------+
I've tried several different join statements -- all a variation of the below. I'm not that well versed in MySQL queries, however.
SELECT * FROM table_1 LEFT JOIN table_2 on table_1.id = table_2.table1_id
Which produces...
+----+----------+----------+----------+------------+-----------+
| id | mid | name | author | key | value |
+----+----------+----------+----------+------------+-----------+
| 1 | 1 | First | Me | desc | hello |
| 1 | 2 | First | Me | begin_day | monday |
| 1 | 3 | First | Me | end_day | tuesday |
| 2 | 4 | Second | You | desc | goodbye |
| 2 | 5 | Second | You | begin_day | wednesday|
| 2 | 6 | Second | You | end_day | friday |
Obviously, iterating over this join statement produces 6 results, 1 for each row in table 2 that matches the id in table 1. How can I avoid this with a proper query statement?
Thank you in advance.
You can use a case statement if you know all of the columns you will be getting, as follows:
Select distinct table_1.*,
case when table_2.key='desc' then value end as desc,
case when table_2.key='begin_day' then value end as begin_day,
case when table_2.key='end_day' then value end as end_day
FROM table_1 LEFT JOIN table_2 on table_1.id = table_2.table1_id
Hope this helps!
SELECT
table_1.*,
MAX(IF(key='desc', value, NULL)) AS 'desc',
MAX(IF(key='begin_day', value, NULL)) AS begin_day,
MAX(IF(key='end_day', value, NULL)) AS end_day
FROM table_1
LEFT JOIN table_2 ON (id = table1_id)
GROUP BY id;