I'm really really a newbie to this so I hope i can explain myself with what I am having trouble with.
I have several tables that i need to extract data from into 1 table. So far I am able to extract from 2 tables but not from 3 or more.
This is what I have from extracting from 2 tables:
select C.id , C.business, AP.firstname, AP.lastname from claims C JOIN affected_people AP ON C.ID = AP.claimid
I have another table name named 'Messages' which I need to extract 'comments and dateread'.
This table relates to the others via 'claimid'.
How do I extract from all three into 1 table?
Help please.
D_Klutz
I did not contemplate an issue I am having with the results obtained. Turns out that there are mutliple messages sent out per claimid but we are looking for is the very last message. How can it be coded to select only the very last message? All messages sent have a timestamp on it. Thanks for your help
Adding another join on Messages should work:
select
C.id ,
C.business,
AP.firstname,
AP.lastname,
M.comments,
M.dateread
from
claims C
JOIN
affected_people AP
ON C.ID = AP.claimid
join
Messages M
on M.claimid = C.ID
Your query should be like this.
select
C.id ,
C.business,
AP.firstname,
AP.lastname,
m.comments,
m. dateread
from
claims C
JOIN
affected_people AP ON C.ID = AP.claimid
JOIN
Messages M on C.ID=M.claimid
Try it
select C.ID, C.business, AP.firstname, AP.lastname, M.Message from claims AS C INNER JOIN affected_people as AP ON C.Id = AP.claimid inner join Messages as M on C.ID = M.claimid
Related
I have 2 tables conversation and participants, I would like to get the list of conversations and participants in each of them. Can I do that in only one query or I have to do 2 queries one for conversation and the second for getting participants for each conversation ?
I tried with
SELECT c.*, (SELECT p.user FROM participants p WHERE p.conversation_id = c.id ) AS participants
FROM `conversation` c
ORDER BY c.date DESC
But i get "error 1242 subquery returns more than 1 rows" and that's normal !
Use an INNER JOIN to select parts of different tables where a common ID is shared. Like this:
SELECT c.*, p.user
FROM conversation AS c INNER JOIN participants AS p ON p.conversation_id = c.id
ORDER BY c.date DESC
Right now you are using a subquery
(SELECT p.user FROM participants p WHERE p.conversation_id = c.id )
to receive a new column, in the table you are creating. A column only has one value for every row, not multiple values. So an error is thrown in this case. If you are confident that you will not miss data then you could force your subquery to return one each time it is run with aggregates
(SELECT max(p.user) FROM participants p WHERE p.conversation_id = c.id )
But if the multiple values are different and still important, which in most cases is likely you want to do the join as mentioned by my friend Erik.
A join is likely what you are looking for.
SELECT c.*, p.user
FROM conversation c
inner join
Participants p
on p.conversation_id = c.id
ORDER BY c.date DESC
I have three mySQL-tables like this:
client network activities
\_id \_id \_id
\_name \_name \_client_id
\_[...] \[...] \_[...]
\_network_id
Now I want to have the following result:
client.*, network.name, number_of_activities_for_each_client
Actually I have this select-statement:
select client.*, network.name
from client
left join network
on client.network_id = network.id
How do I extend the statement? I would also like to see all clients.
SELECT c.*, n.name, COUNT(a.id) number_of_activities_for_each_client
FROM clients c
LEFT JOIN network n
ON n.id = c.network_id
LEFT JOIN activities a
ON a.client_id = c.id
GROUP BY c.id
I'm currently retrieving data from 3 different tables. One of those tables contain messages sent which relates to each ID.
What I'm currently trying to do but have been unsuccessful is retrieve the last message on record for each ID.
Help please-
select
C.id ,
C.business,
AP.firstname,
AP.lastname,
M.comments,
M.dateread
from
claims C
JOIN
affected_people AP
ON C.ID = AP.claimid
join
Messages M
on M.claimid = C.ID
Not sure, if that works for mysql:
select *
from(
select
C.id ,
C.business,
AP.firstname,
AP.lastname,
M.comments,
M.dateread,
max(M.dateread) over (partition by c.id) max_dateread
from
claims C
JOIN
affected_people AP
ON C.ID = AP.claimid
join
Messages M
on M.claimid = C.ID)
where max_dateread=dateread
Just add in
Order by M.dateread desc
I have three tables in Mysql that are link together:
Profile (ID, Name, Stuff..)
Contact(ID, ProfileID,desc,Ord)
Address(ID,ProfileID, desc, Ord)
Now I need to select all profile from the profile table, with the “desc” field from Contact and Address where Ord = 1. (this is for a search function where in a table I’ll display the name, main contact info and main Address of a client.
I can currently do this with three separate SQL request:
SELECT Name, ID FROM Profile WHERE name=”bla”
Then in a foreach loop, I’ll run the other two requests:
SELECT ProfileID, desc FROM Contact WHERE ProfileID=MyProfileID AND Ord=1
SELECT ProfileID, desc FROM Address WHERE ProfileID=MyProfileID AND Ord=1
I know you can do multiple SELECT in one query, is there a way I could group all three SELECT into one query?
You should be able to JOIN the tables on the profile.id and the profileid in the other tables.
If you are sure the profileid exists in all three tables, then you can use an INNER JOIN. The INNER JOIN returns matching rows in all of the tables:
select p.id,
p.name,
c.desc ContactDesc,
a.desc AddressDesc
from profile p
inner join contact c
on p.id = c.profileid
inner join address a
on p.id = a.profileid
where p.name = 'bla'
and c.ord = 1
and a.ord = 1
If you are not sure that you will have matching rows, then you can use a LEFT JOIN:
select p.id,
p.name,
c.desc ContactDesc,
a.desc AddressDesc
from profile p
left join contact c
on p.id = c.profileid
and c.ord = 1
left join address a
on p.id = a.profileid
and a.ord = 1
where p.name = 'bla'
If you need help learning JOIN syntax, here is a great visual explanation of joins
This query below only selects column when an ID from Profile table has atleast one match on tables: Contact and Address. If one or both of them are nullable, use LEFT JOIN instead of INNER JOIN because LEFT JOIN displays all records from the Left-hand side table regardless if it has a match on other tables or not.
SELECT a.*,
b.desc as BDESC,
c.desc as CDESC
FROM Profile a
INNER JOIN Contact b
ON a.ID = b.ProfileID
INNER JOIN Address c
ON a.ID = c.ProfileID
WHERE b.ORD = 1 AND
c.ORD = 1 AND
a.Name = 'nameHERE'
The LEFT JOIN version:
SELECT a.*,
b.desc as BDESC,
c.desc as CDESC
FROM Profile a
INNER JOIN Contact b
ON a.ID = b.ProfileID AND b.ORD = 1
INNER JOIN Address c
ON a.ID = c.ProfileID AND c.ORD = 1
WHERE a.Name = 'nameHERE'
To further gain more knowledge about joins, kindly visit the link below:
Visual Representation of SQL Joins
i have created working demo as your requirement :
The query bellow will retrieve all matching records from the database.its retrieving profile id,name stufff and description of contact tables
select p.id,p.name,p.stauff,c.descr,a.descr from profile as p
inner join contact as c on c.profileid=p.id
inner join address as a on a.profileid=p.id
where p.name="bla" and c.ord=1 and a.ord=1
I am working on expanding user profiles for my project, adding more info. I was just adding countries, when I hit a problem. This is my query for selecting all profile data needed:
SELECT c.*, d.username, d.email, e.country_name
FROM user_profiles c, users d, country e
WHERE c.user_id = ".$id." AND d.id = ".$id."
AND e.country_name = (SELECT country_name FROM country WHERE id = c.country_id)
c.* should select all columns from user_profiles.
The $id is an id of user selecting wich profile should be returned. The problem is, keeping registration as simple as possible, I dont have a country selector there. So when this query comes in action, column country_id from user_profiles is empty, that means when I want to return the country_name, the query result is empty, so no profile data is returned.
I have tried to rewrite this with CASE or LEFT JOIN, but I think I am missing something. I want to find if country_id is not null, when it is not, select also country_name with this country_id. Any ideas?
Thank you kindly for responds.
You can use a LEFT JOIN, but it would be so much easier to do that if you started off by using the cleaner and more modern JOIN syntax:
SELECT c.*, d.username, d.email, e.country_name
FROM user_profiles c
JOIN users d ON d.id = c.id
JOIN country e ON e.country_id = c.country_id
WHERE c.user_id = 42
Now to solve your problem you can just add LEFT:
LEFT JOIN country e ON e.country_id = c.country_id
Full query:
SELECT c.*, d.username, d.email, e.country_name
FROM user_profiles c
JOIN users d ON d.id = c.id
LEFT JOIN country e ON e.country_id = c.country_id
WHERE c.user_id = 42
Related
Why isn't SQL ANSI-92 standard better adopted over ANSI-89?
Before I even start thinking about your current problem, can I just point out that your current query is a mess. Really bad. It might work, it might even work efficiently - but it's still a mess:
SELECT c.*, d.username, d.email, e.country_name
FROM user_profiles c, users d, country e
WHERE d.id = ".$id."
AND d.id = c.user_id
AND e.id = c.country_id;
I have tried to rewrite this with CASE or LEFT JOIN
But you're not going to show us your code?
One solution would be to use a sub select against each row in user_profiles/users:
SELECT c.*, d.username, d.email,
(SELECT e.country_name
FROM country e
WHERE AND e.id = c.country_id LIMIT 0,1) AS country_name
FROM user_profiles c, users d
WHERE d.id = ".$id."
AND d.id = c.user_id;
Alternatively, use a LEFT JOIN:
SELECT c.*, d.username, d.email, e.country_name
FROM user_profiles c
INNER JOIN users d
ON d.id = c.user_id
LEFT JOIN country e
ON e.id = c.country_id
WHERE d.id = ".$id.";