MySQL, Join two rows from one table and ignore doublons - mysql

I have a table "user" like this :
| uid | username |
| 1 | Jack |
| 2 | John |
| 3 | Robert |
Using my request :
SELECT u1.username, u2.username FROM user u1 JOIN user u2
Using this request, I get a table like this :
| uid | username | uid | username |
| 1 | Jack | 1 | Jack |
| 1 | Jack | 2 | John |
| 1 | Jack | 3 | Robert |
| 2 | John | 1 | Jack |
| 2 | John | 2 | John |
| 2 | John | 3 | Robert |
| 3 | Robert | 1 | Jack |
| 3 | Robert | 2 | John |
| 3 | Robert | 3 | Robert |
How can I remove one of these duets?
| 1 | Jack | 2 | John |
| 2 | John | 1 | Jack |

You want all combinations of User table 1 with User table 2. I believe this would accomplish this:
SELECT u1.id, u1.name, u2.id u2.name
FROM User u1
INNER JOIN User u2
WHERE u1.id >= u2.id
This would give the following result:
| uid | username | uid | username |
| 1 | Jack | 1 | Jack |
| 2 | John | 1 | Jack |
| 2 | John | 2 | John |
| 3 | Robert | 1 | Jack |
| 3 | Robert | 2 | John |
| 3 | Robert | 3 | Robert |

Related

in a m to n table between PKs of table A and B. how to find a PK of A that has a specific set of entries with PKs of B in the m to n table

Given the two tables teacher and student,
table : teacher
+-------+-----------+
| id | name |
+-------+-----------+
| 1 | John |
| 2 | Mary |
| 3 | Jeff |
| 4 | Bill |
| 5 | Bob |
| 6 | Frieda |
+-------+-----------+
table : student
+-------+-----------+
| id | name |
+-------+-----------+
| 1 | mario |
| 2 | lisa |
| 3 | anna |
| 4 | sara |
| 5 | felix |
+-------+-----------+
and the m to n relationship between them
table : teacherStudent
+---------+---------+
|teacherId|studentId|
+---------+---------+
| 1 | 1 |
| 1 | 2 |
| 1 | 3 |
| 3 | 1 |
| 3 | 5 |
| 4 | 4 |
| 4 | 5 |
| 5 | 1 |
| 5 | 2 |
| 5 | 3 |
| 6 | 1 |
| 6 | 2 |
| 6 | 3 |
| 6 | 4 |
+---------+---------+
how to find all teacherId that stand in relation to (exactly) studentId 1,2 and 3 ?
I want my final results to look like this:
+----------+
|teacherId |
+----------+
| 1 |
| 5 |
+----------+

MySQL: gets the id instead of the value

I have two tables in my database.
Men table:
+----------------------------------------
| ID | menname | partner |
+----------------------------------------
| 1 | Mark | 1 |
| 2 | Adam | 2 |
----------------------------------------+
Women table:
+---------------------------------------+
| ID | womenname |
+---------------------------------------+
| 1 | Lisa |
| 2 | Emma |
+---------------------------------------+
When I do a inner join, I get:
+----------------------------------------
| ID | menname | partner |
+----------------------------------------
| 1 | Mark | 1 |
| 2 | Adam | 2 |
----------------------------------------+
instead of:
+----------------------------------------
| ID | menname | partner |
+----------------------------------------
| 1 | Mark | Lisa |
| 2 | Adam | Emma |
----------------------------------------+
It gets the id, instead of the partner name.
Anyone know what is wrong with my query?
SELECT m.ID
,m.menname
,w.womenname AS partner
FROM Men AS m
INNER JOIN Women AS w ON m.partner = w.ID;

MySQL - How do I select most recent row for a particular user ID (and filter out duplicates), based on the product type purchased?

I have two tables in a database I'm running a query on:
Table 1 contains the product ID and the type of product it is (e.g. product IDs 1 & 2 are 'lawnmowers', product IDs 3 & 4 are 'leafblowers')
Table 2 contains the user purchases, which has a product ID column (but not product type). Product ID corresponds to the first table. Each user has the same user_ID across multiple purchases, but also a unique purchase ID. This table also contains user data such as first_name, last_name, and company.
I am running a query on product types (e.g. lawnmower), to get all of the people who bought lawnmowers, and then remove duplicate users for people who bought multiple lawnmowers (I want only the latest purchase for each person). I'm filtering by user_id and only using the maximum value for purchase id (the latest one).
This is where the query is at:
SELECT *
FROM purchases t1
INNER JOIN
(
SELECT p1.user_id, MAX(p1.purchase_id) AS max_purchase_id
FROM purchases p1
INNER JOIN products p2
ON p1.product_id = p2.product_id
WHERE p2.product_type = 'lawnmowers'
GROUP BY p1.user_id
) t2
ON t1.user_id = t2.user_id AND t1.purchase_id = t2.max_purchase_id;
This query is filtering out duplicate user_ids, however I'm also needing to filter out people who have the same data in first_name, last_name, and company in table 2 with different user_ids (keeping only the latest). How do I modify the existing query to filter out this data?
Sample data table 1 (before running query):
| product_id | product |
| ------------- | ------------- |
| 1 | lawnmower |
| 2 | lawnmower |
| 3 | leafblower |
| 4 | leafblower |
Sample data table 2 (before running query):
| purchase_id | product_id | user_id | first_name | last_name | company |
| ------------- | -----------| ------------- | ----------- | --------- | ----------- |
| 1 | 1 | 777 | Sally | Smith | My Homeware |
| 2 | 2 | 777 | Sally | Smith | My Homeware |
| 3 | 1 | 777 | Sally | Smith | My Homeware |
| 4 | 2 | 790 | Sally | Smith | My Homeware |
| 5 | 1 | 800 | Billy | Smith | My Homeware |
| 6 | 2 | 800 | Billy | Smith | My Homeware |
| 7 | 1 | 900 | Billy | Smith | My Homeware |
| 8 | 4 | 800 | Billy | Smith | My Homeware |
| 9 | 4 | 800 | Billy | Smith | My Homeware |
| 10 | 4 | 900 | Billy | Smith | My Homeware |
| 11 | 1 | 950 | Bobby | Smith | Cook with B |
Current output:
| purchase_id | product_id | user_id | first_name | last_name | company |
| ------------- | -----------| ------------- | ----------- | --------- | ----------- |
| 3 | 1 | 777 | Sally | Smith | My Homeware |
| 4 | 2 | 790 | Sally | Smith | My Homeware |
| 9 | 4 | 800 | Billy | Smith | My Homeware |
| 10 | 4 | 900 | Billy | Smith | My Homeware |
| 11 | 1 | 950 | Bobby | Smith | Cook with B |
Expected output:
| purchase_id | product_id | user_id | first_name | last_name | company |
| ------------- | -----------| ------------- | ----------- | --------- | ----------- |
| 4 | 2 | 790 | Sally | Smith | My Homeware |
| 7 | 1 | 900 | Billy | Smith | My Homeware |
| 11 | 1 | 950 | Bobby | Smith | Cook with B |

MySQL query is returning duplicates when it shouldn't

I have three tables:
Person
+--------+-----------+
| fName | lName |
+--------+-----------+
| Paul | McCartney |
| John | Lennon |
| Jon | Stewart |
| Daniel | Tosh |
| Steven | Colbert |
| Pink | Floyd |
| The | Beatles |
| Arcade | Fire |
| First | Last |
| Andrew | Bird |
+--------+-----------+
Publication
+----+---------------------------------------+------+-----------+---------+
| id | title | year | pageStart | pageEnd |
+----+---------------------------------------+------+-----------+---------+
| 9 | The Dark Side of the Moon | 1973 | 0 | 0 |
| 10 | Piper At The Gates of Dawn | 1967 | 0 | 0 |
| 11 | Sgt. Pepper's Lonely Hearts Band Club | 1967 | 0 | 0 |
| 12 | Happy Thoughts | 2007 | 0 | 60 |
| 13 | Wish You Were Here | 1975 | 0 | 0 |
| 14 | Funeral | 2004 | 0 | 0 |
+----+---------------------------------------+------+-----------+---------+
Person_Publication
+-----------+----------------+--------+---------------+
| person_id | publication_id | editor | author_number |
+-----------+----------------+--------+---------------+
| 11 | 11 | 0 | 1 |
| 12 | 11 | 0 | 1 |
| 16 | 9 | 0 | 1 |
| 17 | 11 | 0 | 1 |
+-----------+----------------+--------+---------------+
I'm trying to select all authors of a certain publication using the following query:
SELECT fName , lName
FROM Publication , Person, Person_Publication
WHERE Person.id = Person_Publication.person_id
AND Person_Publication.publication_id = 11;
But the results I get are always duplicates (always 6x for some reason). The results:
+-------+-----------+
| fName | lName |
+-------+-----------+
| Paul | McCartney |
| John | Lennon |
| The | Beatles |
| Paul | McCartney |
| John | Lennon |
| The | Beatles |
| Paul | McCartney |
| John | Lennon |
| The | Beatles |
| Paul | McCartney |
| John | Lennon |
| The | Beatles |
| Paul | McCartney |
| John | Lennon |
| The | Beatles |
| Paul | McCartney |
| John | Lennon |
| The | Beatles |
+-------+-----------+
18 rows in set (0.03 sec)
Can somebody please tell me why this is happening and how to fix this?
You are getting 6x your results, exactly one for each Publication row.
Remove your Publication from your FROM clause:
SELECT fName , lName
FROM Person, Person_Publication
WHERE Person.id = Person_Publication.person_id
AND Person_Publication.publication_id = 11;
You are including three tables in your query:
FROM Publication, Person, Person_Publication
but you have only one join condition:
WHERE Person.id = Person_Publication.person_id
You end up with a cartesian product between Publication and Person JOIN Person_Publication
Add the following condition to your WHERE block:
AND Publication.id = Person_Publication.publication.id
A perfect example of why the explicit JOIN syntax is prefered. With the following syntax:
SELECT fName, lName
FROM Publication
JOIN Person_Publication ON Person_Publication.publication.id = Publication.id
JOIN Person ON Person.id = Person_Publication.person_id
WHERE Person_Publication.publication_id = 11;
.. such a mistake simply cannot happen.

MYSQL query: All records where user=jack from table `B` must be returned with the corresponding color matching `photo_id`

Here are two overly simplified version of 2 tables I'm using:
A:
+-------+-----------------------+
| id | photo_id | color |
+-------+-----------------------+
| 1 | 100 | red |
| 2 | 101 | blue |
| 3 | 102 | green |
+-------+-----------------------+
B:
+-------+-----------------------+
| id | photo_id | user |
+-------+-----------------------+
| 1 | 100 | jack |
| 2 | 101 | jill |
| 3 | 102 | jack |
| 4 | 103 | jill |
| 5 | 104 | jack |
| 6 | 105 | jack |
| 7 | 106 | jack |
+-------+-----------------------+
This is the query I'm running right now:
SELECT * FROM B WHERE user='jack';
But, now I need to get the following result
C:
+-------+-----------------------+--------+
| id | photo_id | user | color |
+-------+-----------------------+--------+
| 1 | 100 | jack | red |
| 2 | 102 | jack | blue |
| 3 | 104 | jack | green |
| 4 | 105 | jack | |
| 5 | 106 | jack | |
+-------+-----------------------+--------+
All records where user=jack from table B must be returned with the corresponding color matching photo_id.
How can this be done?
Untested, but here goes:
SELECT * FROM B LEFT JOIN A ON A.photo_id = B.photo_id WHERE user = 'jack'
select * from B LEFT JOIN A using(photo_id) where B.user = 'jack';