How to select distinct rows when using joint table - mysql

I have two tables named chatMaster and chatMessages , i was trying to left join the two tables to get all data from master and latest message for each chat. I am using this query to join the two tables
SELECT c.id, c.p1, c.p2, m.toP, m.message, m.createdOn FROM chatMaster c
left join chatMessages m on c.id = m.id group by m.id ;
This query is for selecting only one row for each entry in chatMaster, but it is selecting the first message for every entry like,
1, 2018-11-24 00:40:08, HI!, 99e22056-ee7f-11e8-bc28-8acac6f59ef9, 1001
2, 2018-11-24 00:40:21, HI! There, 99e22056-ee7f-11e8-bc28-8acac6f59ef9, 1
3, 2018-11-24 01:33:12, HI!, e3345a17-ee7f-11e8-bc28-8acac6f59ef9, 2
this is the result of select * from chatMessages, There are two entries for chat id 99e22056-ee7f-11e8-bc28-8acac6f59ef9 and i want the send one which is send on 2018-11-24 00:40:21 but the result of my join query is
99e22056-ee7f-11e8-bc28-8acac6f59ef9, 1001, 1, 1001, HI!, 2018-11-24 00:40:08
e3345a17-ee7f-11e8-bc28-8acac6f59ef9, 2, 10001, 2, HI!, 2018-11-24 01:33:12
It is selecting the first message. How to select the latest message? What changes should i make to get the latest message from chatMessages instead of first message. please ask if you need more details

In a Derived Table, you can get the maximum values of createdOn (latest createdOn) for every chat-master id. You can then join this result-set to the main table, to get only the row corresponding to latest createdOn.
SELECT c.id, c.p1, c.p2, m.toP, m.message, m.createdOn
FROM chatMaster c
LEFT JOIN
( SELECT id, MAX(createdOn) AS latest_createdOn
FROM chatMessages
GROUP BY id
) AS dt
ON dt.id = c.id
LEFT JOIN chatMessages m
ON m.id = c.id AND
m.createdOn = dt.latest_createdOn

Related

query make a count to 1 which does not satistfy the condition

i have a two table i want to know the number of person who are all assigned to project in each sector
CREATE TABLE first1( a int,projectname varchar(20));
INSERT INTO first1 VALUES
(1001,'crm'),
(1002,'iic'),
(1003,'abc'),
(1004,'sifty bank');
CREATE TABLE diff(b int,name varchar(20),p_id int );
INSERT INTO diff VALUES
(101,'priya',1001),
(102,'divya',1002),
(103,'sidhu',null),
(104,'shiva',null),
(105,'surya',1002);
Query:
select first1.projectname,count(*) from first1 left join diff on first1.a=diff.p_id group by
first1.projectname;
The output of this code is:
abc|1
crm|1
iic|2
sifty bank|1
The expected output is :
abc|0
crm|1
iic|2
sifty bank|0
The problem is count(*); it counts how many rows there are in each group - A project without any person assigned still counts as 1. Instead, you need to count() something from the left table, so null values are not taken into account:
select f.projectname, count(d.p_id) as cnt_diff
from first1 f
left join diff d on f.a = d.p_id
group by f.projectname;
Note that you can get the same result with a subquery:
select f.projectname,
(select count(*) from diff d where d.p_id = f.a) as cnt_diff
from first1 f

Not getting the expected result when using mysqlQuery duplicate some values

I am trying to fetch data from 4 tables and I wrote one query
SELECT
c.id,
c.name,
c.price,
c.duration,
c.period,
c.practical_classes,
c.theory_classes,
e.id,e.created_at,
u.id,
u.registration_no,
i.id,
i.amountpaid,
(i.amount - i.amountpaid) as balanceamount
FROM
courses c,
coursesenrolled e,
users u,
invoices i
WHERE e.student = "11"
AND e.course = c.id
AND c.delete_status = "0"
AND c.status = "Available"
AND u.id = "11"
AND i.student = e.student
and I am getting the result is like below image here raws are duplicating. if I add GROUP BY in my query the last 3 columns getting the wrong data
the below result which I am getting if I add Group By
Below I am attaching the table format
1. "Course",
2. "coursesenrolled" which is handling data which course is assigned to which users
3."user"
4. invoices which will handling invoice for users
I try to understand the question, so you wanna get the result for user with id=11, right? Try this one
SELECT DISTINCT c.id,c.name,c.price,c.duration,c.period,c.practical_classes,c.theory_classes,e.id,e.created_at,u.id,u.registration_no,i.id,i.amountpaid,(i.amount-i.amountpaid) as balanceamount FROM courses AS c INNER JOIN coursesenrolled AS e ON e.course=c.id INNER JOIN users AS u ON u.id=e.student INNER JOIN invoices AS i ON i.student=u.id WHERE u.id='11' AND c.delete_status='0' AND c.status='Available';

LEFT JOIN functionality in a (maybe) double joined query with WHERE

I have the following 3 tables:
Clients AS c
--------
ClientID,
ClientGUID,
InitializationDate,
LastCheckin
ClientServices AS cs
---------------
ClientID,
ServiceID,
Status,
Version
Services AS s
---------
ServiceID,
Name,
Description
I need to build a query that will give me the following results:
s.Name, cs.Version
I need it to act as a left join, in the sense that I'd like to have all Services display, regardless of whether that service is in ClientServices. The selected version will simply display as NULL in this case.
I tried doing some simple joins, but every combination of LEFT JOIN and JOIN I used resulted in ONLY the ClientServices that belonged to that client showing up. An example:
SELECT s.`Name`,
cs.`Version`
FROM `Services` s LEFT JOIN ClientServices cs ON
s.`ServiceID` = cs.`ServiceID`
JOIN Clients c ON
cs.`ClientID` = c.`ClientID`
WHERE `ClientGUID`='thisisanewguid'
I was able to finally get the desired result with this query:
SELECT s.`Name`,
cs.`Version`
FROM `Services` s LEFT JOIN ClientServices cs
ON s.`ServiceID` = cs.`ServiceID`
WHERE cs.ClientID = (
SELECT ClientID
FROM Clients
WHERE ClientGUID='thisisanewguid'
)
OR cs.ClientID IS NULL
but I feel as though its a little "hacky". Is there a better way to get the same result set, but without doing multiple selects in one query? (preferably with only joins, but I'm not sure if thats possible anymore)
Example Data Set:
Clients:
ClientID, ClientGUID, InitializationDate, LastCheckin
1, 'xxxxxxxxxxxxxxxx', 10/10/2017, 10/12/2017
2, 'thisisanewguid', 05/23/2017, 10/12/2017
ClientServices:
ClientID, ServiceID, Status, Version
1, 1, 1, '0.1'
2, 1, 1, '0.1'
2, 2, 1, '0.2'
Services:
ServiceID, Name, Description
1, InITManager, 'Manages and updates all InIT services.'
2, InITIAM, 'InIT's Inventory/Asset Management.'
3, InITTesting, 'testing'
Desired Result Set WHERE ClientGUID='thisisanewguid':
Name, Version
InITManager, '0.1'
InITIAM, '0.2'
InITTesting, NULL
for obatin the result you showed in question you could use left table with left join without where clause for column involved id left join
SELECT s.`Name`,
cs.`Version`
FROM `Services` s
LEFT JOIN ClientServices cs ON s.`ServiceID` = cs.`ServiceID`
LEFT JOIN Clients c ON c.ClientID = cs.ClientID AND c.`ClientGUID`='thisisanewguid'
Hi can you please try the following query
SELECT cs.Version, s.Name
FROM ClientServices cs
RIGHT JOIN Clients c ON c.ClientID = cs.ClientID
RIGHT JOIN Services s ON s.ServiceID = cs.ServiceID

SQL: count rows from 3rd table

I have 3 tables, the first table is the account_has_account1 where i store the relation between accounts and it's columns are account_id, account_id1, status where account_id is the account doing following to account_id1 and status is an enum type with values active, inactive where active indicates if the account is actually following, if it's inactive, then account stopped following.
the second table is named account_has_photos which i store the photos one account has stored in the database, so it's columns are account_id, photos_id, so i need this table to get all photos from one account which another account is following.
But all these have messages posted on them, and here is where the 3rd table comes which is named photos_has_message_photos, from this table i only need a count of all posted messages in one photo, the columns are photos_id, message_photos_id
for now my query is this:
SELECT account_has_photos.photos_id as id, "photos" as type, account_has_photos.update_at, account_has_photos.account_id
FROM account_has_account1
JOIN account_has_photos
ON (account_has_photos.account_id = account_has_account1.account_id1 AND account_has_photos.type_id = 17)
WHERE account_has_account1.account_id = 7 AND account_has_account1.`status` = "Active"
it shows all photos from accounts on which account id 7 is following, but on my attempts on getting the total messages have failed, i thought on doing an INNER JOIN like this:
INNER JOIN (
SELECT photos_has_message_photos.photos_id, count(photos_has_message_photos.photos_id) as total
FROM photos_has_message_photos
) posts
ON(posts.photos_id = account_has_photos.photos_id)
and then i select from main posts.total, but it does not show any row, not even the photos, the result is empty at this point and i have no idea why and what to do.
the complete query is like this:
SELECT account_has_photos.photos_id as id, "photos" as type, account_has_photos.update_at, account_has_photos.account_id, posts.total
FROM account_has_account1
JOIN account_has_photos
ON (account_has_photos.account_id = account_has_account1.account_id1 AND account_has_photos.type_id = 17)
INNER JOIN (
SELECT photos_has_message_photos.photos_id, count(photos_has_message_photos.photos_id) as total
FROM photos_has_message_photos
) posts
ON(posts.photos_id = account_has_photos.photos_id)
WHERE account_has_account1.account_id = 7 AND account_has_account1.`status` = "Active"
again, i only need a total of rows which are messages from each photos found
Try this query updated inner select
SELECT ahp.photos_id as id, "photos" as type, ahp.update_at, ahp.account_id,posts.total
FROM account_has_account1
JOIN account_has_photos
ON (ahp.account_id = account_has_account1.account_id1 AND ahp.type_id = 17) INNER JOIN (
SELECT phmp.photos_id, count(*) as total FROM photos_has_message_photos GROUP BY phmp.photos_id
) posts
ON(posts.photos_id = ahp.photos_id) WHERE account_has_account1.account_id = 7 AND account_has_account1.`status` = "Active"

Relating the values one table to another table

I have two tables. One is named usertbl with columns user_id, user_name, and acct_status. possible values for acct_status values are 0, 1, 2, 3. Another table named accountstatustbl has the following columns - acct_status, and acct_status_desc, with values when acct_status = 0, acct_status_desc = enrolled, 1 = active, 2 = inactive, and 3 = deactivated. Now, how should I query my db to provide me the following output:
user_id user_name status
0000000 user1 enrolled
1234567 user2 active
9999999 user3 deactived
instead of giving me values 0, 1, and 3?
You can try this.
SELECT user.user_id, user.user_name, status.description
FROM usertbl user left outer join accountstatustbl status
on user.acct_status=status.acct_status
SELECT u.user_id, u.username, s.acct_status_desc status
FROM usertbl u, accountstatustbl s
WHERE u.acct_status = s.acct_status
Hope I helped.
you can use INNER JOIN assuming that acct_status in usertbl has no NULL values:
SELECT a.user_id,
a.user_name,
b.status_desc AS status
FROM usertbl a
INNER JOIN accountstatustbl b
ON b.acct_status = a.acct_status
you can also read about MySQL JOIN Syntax to understand more about joins