mySQL Query JOIN in same table - mysql

Table structure goes something like this:
Table: Purchasers Columns: id | organization | city | state
Table: Events Columns: id | purchaser_id
My query:
SELECT purchasers.*, events.id AS event_id
FROM purchasers
INNER JOIN events ON events.purchaser_id = purchasers.id
WHERE purchasers.id = '$id'
What I would like to do, is obviously to select entries by their id from the purchasers table and join from events. That's the easy part. I can also easily to another query to get other purchasers with the same organization, city and state (there are multiples) but I'd like to do it all in the same query. Is there a way I can do this?
In short, grab purchasers by their ID but then also select other purchasers that have the same organization, city and state.
Thanks.

You could try something like
SELECT p.*,
e.id
FROM purchasers p INNER JOIN
events e ON e.purchaser_id = p.id INNER JOIN
(
SELECT p.*
FROM purchasers p
WHERE p.id = '$id'
) Original ON p.organization = Original.organization
AND p.city = Original.city
AND p.state = Original.state
The subselect Original will return the original purchaser, and then link to the purchasers table by organization, city and state
EDIT:
Changed the query, this will still return duplicates, but only for the number of events registered per purchaser. If you wish to retrieve a DISTINCT list of purchasers, you cannot do this with the event id, so you need something like
SELECT p.*
FROM purchasers p INNER JOIN
(
SELECT p.*
FROM purchasers p
WHERE p.id = '$id'
) Original ON p.organization = Original.organization
AND p.city = Original.city
AND p.state = Original.state

Related

SQL LEFT JOIN for all records of first table and matched records of another table

I have 3 tables.
Table seller with columns like id, name etc.
Table customer like id, name etc.
Table connections which have seller_id, customer_id, status of friendship like "friends", "pending_request" etc.
Now I want to get all the sellers who are not friends of a specific customer.
So I tried like fetching records from seller table with left join of connections table, with condition status is not "friends"
I tried the following query but didn't help me. I also tried other queries but didn't help.
SELECT * FROM `seller` LEFT JOIN `connections` ON seller.user_id = connections.user_id WHERE customer_id = 10 AND request_status NOT LIKE "friends"
Here is the reference screen I want the result. Like for a particular customer, all the sellers who are not friends or request is pending.
Join the connections of type 'friends' for customer_id = 10 and in a WHERE clause check for the connections.user_id being NULL, i.e. nothing has been joined.
SELECT *
FROM seller
LEFT JOIN connections
ON seller.user_id = connections.user_id
AND connections.customer_id = 10
AND connections.request_status = 'friends'
WHERE connections.user_id IS NULL;
Or use a correlated subquery, that gets the connection with a NOT EXISTS.
SELECT *
FROM seller s
WHERE NOT EXISTS (SELECT *
FROM connections c
WHERE c.user_id = s.user_id
AND c.customer_id = 10
AND c.request_status = 'friends');
Try this:
SELECT * FROM `seller` LEFT JOIN `connections` ON seller.user_id = connections.user_id WHERE customer_id = 10 AND (request_status NOT LIKE "friends"
or request_status is null)
Or this:
SELECT * FROM `seller` LEFT JOIN `connections` ON seller.user_id = connections.user_id WHERE customer_id = 10 AND IFNULL(request_status,"other") NOT LIKE "friends"

SELECT records from two table

I have two tables :
PEOPLE
ID |NAME
|A2112 |John
|B3200 |Mary
|C2454 |Bob
|F2256 |Joe
JOBS
|ID |NAME |PEOPLE
|56565 |Taxi Driver |A2112
|23232 |Herborist |A2112
|12125 |Jumper |B3200
|25425 |Taxi Driver |C2454
|12456 |Taxi Driver |F2256
|56988 |Herborist |F2256
|45459 |Superhero |F2256
I wonder how I can select any records FROM People that have JOBS ID 56565 AND 23232 in performant way.
The search pattern may be two or multiples jobs, and the records can have another jobs too.
So the result will be John and Joe in this example.
Not quite sure if I got you right. This will return people who have job 56565 and/or 23232:
select distinct p.name
from people p
join jobs j on p.id = j.peopleid
where j.id in (56565, 23232)
If BOTH jobs are required:
select p.name
from people p
join jobs j on p.id = j.peopleid
where j.id in (56565, 23232)
group by p.name
having count(*) > 1
The HAVING clause can also be written as
having max(j.id) <> min(j.id)
Perhaps better performance that way.
The INNER JOIN keyword selects all rows from both tables as long as there is a match between the columns in both tables.
SELECT
p.NAME, COUNT(*) as tot
FROM
PEOPLE p
INNER JOIN JOBS j ON (p.ID = j.PEOPLE)
WHERE
j.ID IN (56565, 23232)
GROUP BY
p.NAME
HAVING
COUNT(*) > 1
Visual explanation of INNER JOIN bellow:
SELECT * FROM PEOPLE as p
JOIN JOB as j ON j.PEOPLE = p.ID
WHERE j.ID IN(56565, 23232)
"People that have JOBS" translates to WHERE EXISTS in SQL:
select *
from people
where exists
(
select *
from jobs
where jobs.people = people.id
and jobs.id in (56565, 23232)
);
This can also be written with an IN clause, which I even consider slightly more readable for its simplicity:
select *
from people
where id in
(
select people
from jobs
where id in (56565, 23232)
);

Joining two tables for the result?

I have 2 tables in a database person and order tables.
PERSON table:
PERSON_ID | NAME
ORDER table:
ORDER_ID | ORDER_NO | PERSON_ID
I need to display all the orders + a name of corresponding person if it exists, if not just order details.
So far I got up to query:
SELECT ORDER_ID, ORDER_NO, order.PERSON_ID, NAME
FROM person, order
WHERE person.PERSON_ID = order.PERSON_ID AND
person.FIRST_NAME IS NOT NULL;
Which gives me orders only if the name is available whereas I need to display all the orders despite the fact if name is available or not.
Any suggestions?
Yes, you can use LEFT JOIN for that:
SELECT o.order_id, o.order_no, o.person_id, p.name
FROM `order` o
LEFT JOIN person p
ON p.person_id = o.person_id AND p.FIRST_NAME IS NOT NULL
With LEFT JOIN if the name is null it will still give you the orders.

Getting a list of data based on Items associated with User

I have a table called reviews. I get the most current user reviews like this:
SELECT b.item, b.item_id, a.review_id, a.review, c.category, u.username, c.cat_id
FROM reviews a
INNER JOIN items b
ON a.item_id = b.item_id
INNER JOIN master_cat c
ON c.cat_id = b.cat_id
INNER JOIN users AS u
ON u.user_id = a.user_id
ORDER BY a.review_id DESC;
What I want to do is slightly alter it to be more personable for users.
I have another table of user "connections". Kind of like Twitter. When a user follows someone, it gets logged in this table called profile_follow. This has three columns. id, user_id, follow_id. Simply: If I am user #1, and I "follow" user # 3 and user #5, two rows will be added in this table:
profile_follow
------------------------
id | user_id | follow_id
| 1 | 3
| 1 | 5
Here is how I want to change the query above. I want to only show newest reviews, from people you follow.
So I will need at least one more join, for table profile_follow. And I need to pass in a user_id (it's a php function), doing something like `WHERE profile_follow.user_id = '{$user_id}'. I think I will have to add a sub query on this, not use.
Can someone show me how to finish this query? I am not sure how to handle it from here? All of my attempts have been off so far.
I think I need to do something like:
Selectfollow_idwhereuser_id= (logged in user)
And then in the main query:
Select reviews only with profile_follow.follow_id = review.user_id.
I can't figure out how to make this filter work.
Always difficult without testing, but:
SELECT b.item, b.item_id, a.review_id, a.review, c.category, u.username, c.cat_id
FROM reviews a
INNER JOIN items b
ON a.item_id = b.item_id
INNER JOIN master_cat c
ON c.cat_id = b.cat_id
INNER JOIN profile_follow pf
ON pf.follow_id = a.user_id
WHERE profile_follow.user_id = '{$user_id}'
ORDER BY a.review_id DESC;

Select Rows From Second Table Based On id From First

I have 2 tables
1_products
id, code, make, model, fk_group_id
1_stock
id, stock, repair
I want to be able to return all of the rows in both tables based on the match in the first. Say WHERE fk_group_id = 11
Here is one:
SELECT *
FROM products AS p
INNER JOIN stock AS s ON p.id = s.id
WHERE fk_group_id = 11