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
Related
I have three tables, company, user and share. I want to count one company's user and share, they are not relevant.
There may be a row that has share value but not user value. so I used left join, I can get results separately, but it doesn't work together.
Here is my query:
SELECT c.name, count(u.company_id), count(s.company_id)
FROM company c
LEFT JOIN user u
ON c.id=u.company_id and u.company_id=337
WHERE u.company_id is NOT NULL
LEFT JOIN share s
ON c.id=s.id AND s.company_id=337
WHERE s.company_id is NOT NULL
You need to do at least one of the counts in a subquery. Otherwise, both counts will be the same, since you're just counting the rows in the resulting cross product.
SELECT c.name, user_count, share_count
FROM company AS c
JOIN (SELECT company_id, COUNT(*) AS user_count
FROM users
GROUP BY company_id) AS u
ON u.company_id = c.id
JOIN (SELECT company_id, COUNT(*) AS share_count
FROM share
GROUP BY company_id) AS s
ON s.company_id = c.id
WHERE c.company_id = 337
Another option is to count the distinct primary keys of the tables you're joining with:
SELECT c.name, COUNT(DISTINCT u.id) AS user_count, COUNT(DISTINCT s.id) AS share_count
FROM company AS c
JOIN users AS u on u.company_id = c.id
JOIN share AS s ON s.company_id = c.id
WHERE c.company_id = 337
Your code looks okay, except for the extra WHERE clause. However, you probably want COUNT(DISTINCT), because the two counts will return the same value:
SELECT c.name, count(distinct u.company_id), count(distinct s.company_id)
FROM company c LEFT JOIN
user u
ON c.id = u.company_id and u.company_id=337 LEFT JOIN
share s
ON c.id = s.id AND s.company_id=337
WHERE s.company_id is NOT NULL AND u.company_id IS NOT NULL;
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
My expected output:
And I write like below:
SELECT c.cID, s.svcID, s.svcNote
FROM company c
LEFT JOIN service s ON s.cID = c.cID
LEFT JOIN (SELECT MAX(s.svcID) AS svcID
FROM service s
GROUP BY s.cID) AS s1 ON s1.svcID = s.svcID
ORDER BY c.cJoinDate DESC
However, I can't get my expected output and taking very long time to run my query. Can someone help me?
Since you want only those entries with service, you need to use INNER JOIN instead of LEFT JOIN. LEFT JOIN will list all records in Company, including cID = 4.
Try this instead:
SELECT c.cID, s.svcID, s.svcNote
FROM company c
INNER JOIN service s ON s.cID = c.cID
WHERE s.ID = (SELECT MAX(s2.svcID)
FROM service s2
WHERE s1.svcID = s2.svcID
GROUP BY s2.cID)
ORDER BY c.cJoinDate DESC
SELECT c.cID, MAX(s.svcID), s.svcNote
FROM company c
INNER JOIN service s ON s.cID = c.cID
GROUP BY s.cID
ORDER BY c.cJoinDate DESC
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
I'm not that into MySQL joins, so maybe you could give me a hand. I've got the following tables:
Table a
Fields ID,name
Table b
Fields aID,cID,ID,found
Table c
Fields ID,name
The result I want to get is the following: I want all the records where b.found = 1. Of these records I don't want a.id or a.name, but I want the number of records that would have been returned if I would have wanted so. So if there are five records that have b.found = 1 and c.id = (for example) 3, then I want a returned value of 5, c.id and c.name.
Someone is able to do this?
Actually this is what I want to get from the database:
A list of all records in table C and a count of records in table B that has found = 1 and b.c_id = c.id
Table: a
Fields: ID, name
Table: b
Fields: aID, cID, found
Table: c
Fields: ID, name
SELECT c.ID, c.name, COUNT(1)
FROM b
JOIN c ON c.ID = b.cID AND b.found=1
GROUP BY c.ID
SELECT c.id, c.name, COUNT(*)
FROM c
INNER JOIN b
ON c.id = b.c_id
AND b.found = 1
GROUP BY c.id, c.name
SELECT COUNT(*), c.id, c.name
FROM a, b, c
WHERE a.id = b.a.id AND c.id = b.a.id AND b.found = 1 AND c.id = idThatIAmSearchingFor
Apologies if I didn't get the syntax exact, but I believe that's the basic structure you want. The COUNT function returns the number of rows found by the query.
Something like:
SELECT count(`c`.*),
`c`.`id`,
`c`.`name`
FROM `b`
JOIN `c`
ON `c`.`id` = `b`.`c_id`
WHERE `b.found` = 1
I think this would provide the required output -
select count(*), b.cID, c.name from b
inner join c on c.id=b.cID and b.found=1
group by b.cID
SELECT COUNT(*) AS Count, c.id, c.name
FROM b join a on a.id = b.a_id
WHERE b.found = 1
GROUP BY c.Id;
COUNT returns count of records in each group from GROUP BY.