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)
);
Related
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;
SELECT p.id, p.first
FROM people p
LEFT JOIN job j ON ( p.job_id = j.id )
LEFT JOIN favourites f ON ( p.company_id = f.company_id )
WHERE p.company_id = 1
I have 3 tables.
Job Favourites People
Each have company_id inside them. When I try the above it outputs p.id,p.first twice. If I remove one of the JOINs then the output is as expected but without the table which was removed.
As I said in the comments what you have here is just an one-to-many relationship which gives you exactly what you are saying.
Like you have a registry on people and you have two favourites to this people on table favourite. To clarify consider the following situation:
Table people:
id name job_id first
1 John 1 1
2 Campos 2 2
Table job
id job
1 Programmer
2 Developer
Table favourites
company_id desc
1 Blah
2 Bleh
1 Blih
On the above model a people have two favourites registries.
For your model it seems that one people can have only one job, but since you did not specify what the table favourites looks like it is probably the the situation i've shown is generating your problem. So to quickly solve it you can use a DISTINCT command like:
SELECT DISTINCT p.id, p.first
FROM people p
LEFT JOIN job j
ON ( p.job_id = j.id )
LEFT JOIN favourites f
ON ( p.company_id = f.company_id )
WHERE p.company_id = 1
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;
I have three tables persons, jobs, jobs_persons
One person can have multiple jobs.
Person 1 is Technical Support AND Manager
Person 2 is Technical Support
Person 3 Is Manager
Job 1 Technical Support
Job 2 Manager
I need to find a query give me the result for the person who currently is Technical Support AND Manager
The answer would be only Person 1
SELECT persons.*
FROM persons INNER JOIN jobs_persons ON persons.id = jobs_persons.person_id
INNER JOIN jobs ON jobs.id = jobs_persons.job_id
WHERE job.id IN (1,2)
Returns 3 rows
SELECT persons.*
FROM persons INNER JOIN jobs_persons ON persons.id = jobs_persons.person_id
INNER JOIN jobs ON jobs.id = jobs_persons.job_id
WHERE job.id = 1 AND job.id = 2
Returns 0 rows.
I'm currently working on Ruby on Rails.
Somebody can help?
You want to use an OR operator. Using job.id = 1 AND job.id = 2 will only return elements where id equals 1 and at the same time 2. No element can do that. You want elemets where th id is 1 or where the id is 2.
to make it more obvious:
SELECT * FROM table WHERE lastname = 'Smith' AND firstname = 'James';
when executing this you obviously don't want everybody who is called Smith or James. ;-)
EDIT:
Misread the question. what you need is a second join to join the jobs table two times in and join them with the different jobs. It is a bit hard as you didn't show the schema, but this might work:
SELECT persons.*
FROM persons
INNER JOIN jobs_persons jp1 ON persons.id = jp1.person_id
INNER JOIN jobs_persons jp2 ON persons.id = jp2.person_id
INNER JOIN jobs j1 ON j1.id = jp1.job_id
INNER JOIN jobs j2 ON j2.id = jp2.job_id
WHERE j1.id = 1 AND j2.id = 2
Try this to get all the person who has got a job of 1 AND 2 in your associative entity table. No need to hit the job table.
SELECT p.*
FROM persons p
WHERE id in (
SELECT person_id FROM jobs_persons
WHERE job_id IN (1,2)
GROUP BY person_id
HAVING COUNT(*) = 2
);
With your recent comments, it seems you're having performance problems. That's really outside of the scope of this question and answer.
You need to make sure your indexes are in place on the appropriate columns:
jobs_person.job_id
persons.id
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