Joining Tables in MySQL - mysql

I have two tables namely Students & Hobbies with following structure and records:
ID,Name
-----------
9,Peter
10,Steve
ID,Hobby
-----------------
9,dancing
9,singing
10,learning
I want to JOIN these tables and get a unique record from table Students.
I am doing this right now which evolves duplicate records:
SELECT a.Name
FROM Students a
LEFT JOIN Hobbies h ON a.ID =h.ID
This gives :
Name
----------
Peter
Peter
Steve
I got the reason, this is because, the table Hobbies has two records of ID=9 , that is why duplicate records are evolved, but how to retrieve a single record? Please help.
I want this:
Name
-----------
Peter
Steve

SELECT a.ID, a.Name
FROM Students a
LEFT JOIN Hobbies h
ON a.ID = h.ID
GROUP BY a.ID, a.Name
With the GROUP BY, you could then answer questions like "How many hobbies does each student have?"
SELECT a.ID, a.Name, COUNT(*) AS Number_of_Hobbies
FROM Students a
LEFT JOIN Hobbies h
ON a.ID = h.ID
GROUP BY a.ID, a.Name

This is really not the way a JOIN should be used.
left joining an unreferenced table on a constant gets you nothing.
the answer to the question you asked is "use a DISTINCT clause":
SELECT DISTINCT a.Name FROM Students a LEFT JOIN Hobbies h ON a.ID = 9
...but really, I'm pretty sure this is not what you want to do.
based off the comments, I believe what the OP's intent was something like this:
SELECT
a.Name
FROM
Students a
WHERE
a.ID = <Student ID>;
... AND , for the hobbies reference:
SELECT DISTINCT
a.ID,
a.Name
FROM
Students a
INNER JOIN
Hobbies h ON h.ID = a.ID
WHERE
h.Hobby = <Hobby Name>;

Use the distinct keyword:
SELECT distinct a.Name
FROM Students
etc....
It eliminates duplicate rows, so you'll only get one of each name.

You are getting duplicates because Peter has 2 hobbies. If you want a single record per User do this:
select * from Student where Id in (
Select DISTINCT Id from HobbY)

Related

SQL: Group by in subquery

I'm trying to find the output of all books that have more than one genre using a group by statement and subquery. However, it keeps returning Subquery returns more than 1 row. This is what I have so far:
SELECT title
FROM book
WHERE 1 < (SELECT COUNT(genre) FROM genres GROUP BY book_id);
Here's an example:
SELECT b.title
FROM ( SELECT g.book_id
FROM genres g
GROUP
BY g.book_id
HAVING COUNT(1) > 1
) m
JOIN book b
ON b.id = m.book_id
The inline view m is meant to return us values of book_id that appear more than one time in the genres table. Depending on uniqueness constraints, we might want to count distinct values of genre
HAVING COUNT(DISTINCT g.genre) > 1
if we want to find books with exactly three related genre:
HAVING COUNT(DISTINCT g.genre) = 3
Once we have a list of book_id values, we can join to the book table. (The query assumes that book_id in genres is a foreign key reference to the id column in book table.)
You seem to what a correlated subquery:
SELECT b.title
FROM book b
WHERE 1 < (SELECT COUNT(*) FROM genres g WHERE g.book_id = b.book_id);
SELECT distinct a.title
FROM book a, (select bookid,count(distinct genre)genres from genres group by bookid)b
WHERE a.book_id=b.bookid and b.genres>1
hope it helps!

Mysql - Join query

I have the following 2 queries:-
Query 1:-
mysql> select mccid_c, id_c from contacts_cstm where accountnumber_c = '1601480000552527';
250762 | 475093000013882513
Query 2:-
mysql> select first_name, last_name from contacts where id = '475093000013882513';
John | Doe
id in contacts = id_c in contacts_cstm
I required a join query to get mccid_c, first_name, last_name in one query
Thanks!
This is a classic usecase of the join syntax:
SELECT mccid_c, first_name, last_name
FROM contacts_cstm cc
JOIN contacts c ON c.id = cc.id_c
WHERE c.id = '475093000013882513'
You can use multiple tables in your single SQL query. The act of joining in MySQL refers to smashing two or more tables into a single table.
You can use JOINS in SELECT, UPDATE and DELETE statements to join MySQL tables.But firstly you need a common column (attribut),suppose it is 'tutorial_author' between the two tables that you want to join it.
SELECT a.mccid_c, b.first_name , b.last_name
FROM contacts_cstm a, contacts b
WHERE a.tutorial_author = b.tutorial_author and a.accountnumber_c = '1601480000552527' and b.id = '475093000013882513';
I hope it will help you, best regards
Try this.
Select a.mccid_c, b.first_name, b.last_name from contacts_cstm a inner join contacts b where a.id_c=b.id;

row count on inner join

ok i've been trying for 2 days to figure this out. I have 2 tables
Organization_dep
id
orgid
depname
organization_dep_users
id
orgid
depid
userid
I want to list the count of user ids from the departments of the organizations.
Can you try this:
SELECT
b.depname, count(a.id)
FROM organization_dep_users a
INNER JOIN Organization_dep b ON a.depid = b.id
GROUP BY b.depname;
Edit:
Thanks for Barmar for additional details.

Converting Multi-Column query into Rows

I have two queries that I want to join together, but I don't know how to.
Select father, mother, guardian from students where user_id = '201209291';
I get a result of 3 IDs.
Now, I need to use those three IDs to get their personal information;
Select * from system_users where user_id = (The 3 IDs from the previous query);
How would i go about solving this problem? I thought of the result of the first query into 3 rows, but I don't know how to do that either.
Select * from system_users where user_id IN
(
Select father from students where user_id = '201209291'
UNION
Select mother from students where user_id = '201209291'
UNION
Select guardian from students where user_id = '201209291'
)
Well, you can join directly using a series of ORs in the join predicate, as long as the father, mother, and guardian columns are actually user_ids in system_users.
select usrs.*
from students s
join system_users usrs on
s.father=usrs.user_id OR
s.mother=usrs.user_id OR
s.guardian=usrs.user_id
where s.user_id = '201209291';
Why don't you use join?
Select father, mother, guardian from students as s
join system_users usrs
on s.user_id=usrs.user_id
where s.user_id = '201209291';
From the first query you will have not IDs but 3 columns.
Select father, mother, guardian from students where user_id = '201209291'.
Probably you mean
Select distinct some_id from students where user_id = '201209291'
I suggest simple:
Select * from system_users where user_id in (Select distinct some_id from students where user_id = '201209291');
Did I understand the question correctly?

print all duplicate rows

Now, I have the following query, which gives me the COUNT() of rows which have the same name. However, let's say that I just wanted to have all the rows printed out.
SELECT l.id, c.first_name, c.last_name,
l.source AS 'affiliateId', COUNT(*),
c.email, ls.create_date, ls.buyer
FROM lead_status AS ls
INNER JOIN leads AS l ON l.id = ls.lead_id
INNER JOIN contacts AS c ON c.lead_id = l.id
WHERE ls.discriminator = 'AUTO_POST' AND l.affiliate_id=1003
AND ls.winner =1 AND l.test =0
AND l.create_date BETWEEN '2011-10-03' AND '2011-10-19'
GROUP BY c.first_name, c.last_name HAVING COUNT(*)>1;
So I'm trying to go from:
joe smith 3
lisa martin 2
To the following:
joe smith
joe smith
joe smith
lisa martin
lisa martin
Help!
You can join with a numbers table:
SELECT T1.col1, T2.col2
FROM
(
-- your long query goes here
) T1
JOIN numbers
ON numbers.x <= T1.cnt
A numbers table is just a table that contains numbers:
+---+
| x |
+---+
| 1 |
| 2 |
| 3 |
etc... as many numbers as you will ever need
u can use expression COUNT(DISTINCT first_name) and then get rid of GROUP BY
so query will be
SELECT l.id, c.first_name, c.last_name, l.source AS 'affiliateId', COUNT(DISTINCT c.first_name, c.last_name) as CountRows,
c.email, ls.create_date, ls.buyer FROM lead_status AS ls
INNER JOIN leads AS l ON l.id = ls.lead_id
INNER JOIN contacts AS c ON c.lead_id = l.id
WHERE ls.discriminator = 'AUTO_POST' AND l.affiliate_id=1003
AND ls.winner =1 AND l.test =0 AND l.create_date BETWEEN '2011-10-03' AND '2011-10-19'
HAVING CountRows>1
I don't remember if MySQL supports subqueries, but I would do something like
select
first, last
from
table where id in (select id from table group by first, last having count(*) > 1)
order by
first, last
Add another join on the table(s) where the duplication appears. For the join condition, have the identifying info be the same (e.g. c.first_name = c2.first_name AND c.last_name = c2.last_name, or l.id = c2.id) and whatever distinguishes the records be different (e.g. l.create_date < l2.create_date). Lastly, group by the ID of the record that contains the duplicates or select distinct rows so you don't get repeats. Without knowing the table schema or where the duplicates might occur, I can't be any more specific.
join the result set back with the contacts tale on the first name and last name fields (assuming that first name + last name forms a unique key)