How to show multiple table list in mysql
I have a query that has two tables
one for patients and the second one for patients who has tested for covid-19
I want to show all the patients either they tested or not
If tested then show the result with his/her name
It only showing the patients who has tested for the covid not every one
how to solve that please ?
here's my Query
SELECT patient.*
,covidtest.covidTestResult ,subareas.areaname
FROM
( patient LEFT OUTER JOIN subareas
ON patient.town_id = subareas.town_id ) LEFT OUTER join covidtest ON
patient.Idnumber = covidtest.Idnumber where
patient.Idnumber=covidtest.Idnumber and
covidtest.CovidTestDate=(select max(covidtest.CovidTestDate)from
covidtest where patient.Idnumber=covidtest.Idnumber) group by covidtest.Idnumber
UNION SELECT patient.* ,covidtest.covidTestResult,subareas.areaname FROM
( patient LEFT OUTER JOIN subareas ON
patient.town_id = subareas.town_id ) LEFT OUTER join covidtest ON
patient.Idnumber = covidtest.Idnumber where patient.Idnumber=covidtest.Idnumber
and covidtest.CovidTestDate=(select max(covidtest.CovidTestDate) from covidtest where
patient.Idnumber=covidtest.Idnumber) group by covidtest.Idnumber;
here is what you need to do:
SELECT
patient.*,
covidtest.covidTestResult,
subareas.areaname
FROM patient
left join subareas on patient.town_id = subareas.town_id
Left join lateral
( select covidTestResult from covidtest
where patient.Idnumber = covidtest.Idnumber
order by CovidTestDate desc
limit 1
) covidtest on 1=1
Related
I have this table below as a result
SELECT
doctors.`name`,
COUNT(`doctor-barge-naghs`.`code-naghs`) AS 'countEachDoctor'
FROM
doctors
INNER JOIN `doctor-barge-naghs` ON `doctor-barge-naghs`.`code-doctor` = doctors.id
GROUP BY doctors.`name`
and I want to calculate the SUM 'countEachDoctor' field and show
it beside of each row.
I did this
SELECT t1.*,(SELECT SUM(t1.countEachDoctor))
FROM(
SELECT
doctors.`name`,
COUNT(`doctor-barge-naghs`.`code-naghs`) AS 'countEachDoctor'
FROM
doctors
INNER JOIN `doctor-barge-naghs` ON `doctor-barge-naghs`.`code-doctor` = doctors.id
GROUP BY doctors.`name`) AS t1
it is what I wanted but unfortunately ,it just show one records,I need all records.
IF you are not using mysql 8, you can achieve it like this:
SELECT
doctors.`name`,
COUNT(`doctor-barge-naghs`.`code-naghs`) AS 'countEachDoctor',
(SELECT SUM(t.countEachDoctor)
FROM (
SELECT
COUNT(`doctor-barge-naghs`.`code-naghs`) AS 'countEachDoctor'
FROM doctors
INNER JOIN `doctor-barge-naghs` ON `doctor-barge-naghs`.`code-doctor` = doctors.id
GROUP BY doctors.`name`) t) AS sumCount
FROM
doctors
INNER JOIN `doctor-barge-naghs` ON `doctor-barge-naghs`.`code-doctor` = doctors.id
GROUP BY doctors.`name`
I have 7 tables to work with inside a query:
tb_post, tb_spots, users, td_sports, tb_spot_types, tb_users_sports, tb_post_media
This is the query I am using:
SELECT po.id_post AS id_post,
po.description_post as description_post,
sp.id_spot as id_spot,
po.date_post as date_post,
u.id AS userid,
u.user_type As tipousuario,
u.username AS username,
spo.id_sport AS sportid,
spo.sport_icon as sporticon,
st.logo_spot_type as spottypelogo,
sp.city_spot AS city_spot,
sp.country_spot AS country_spot,
sp.latitud_spot as latitudspot,
sp.longitud_spot as longitudspot,
sp.short_name AS spotshortname,
sp.verified_spot AS spotverificado,
u.profile_image AS profile_image,
sp.verified_spot_by as spotverificadopor,
uv.id AS spotverificador,
uv.user_type AS spotverificadornivel,
pm.media_type AS mediatype,
pm.media_file AS mediafile,
GROUP_CONCAT(tus.user_sport_sport) sportsdelusuario,
GROUP_CONCAT(logosp.sport_icon) sportsdelusuariologos,
GROUP_CONCAT(pm.media_file) mediapost,
GROUP_CONCAT(pm.media_type) mediaposttype
FROM tb_posts po
LEFT JOIN tb_spots sp ON po.spot_post = sp.id_spot
LEFT JOIN users u ON po.uploaded_by_post = u.id
LEFT JOIN tb_sports spo ON sp.sport_spot = spo.id_sport
LEFT JOIN tb_spot_types st ON sp.type_spot = st.id_spot_type
LEFT JOIN users uv ON sp.verified_spot_by = uv.id
LEFT JOIN tb_users_sports tus ON tus.user_sport_user = u.id
LEFT JOIN tb_sports logosp ON logosp.id_sport = tus.user_sport_sport
LEFT JOIN tb_post_media pm ON pm.media_post = po.id_post
WHERE po.status = 1
GROUP BY po.id_post,uv.id
I am having problems with some of the GROUP_CONCAT groups:
GROUP_CONCAT(tus.user_sport_sport) sportsdelusuario is giving me the right items but repeated, all items twice
GROUP_CONCAT(logosp.sport_icon) sportsdelusuariologos is giving me the right items but repeated, all items twice
GROUP_CONCAT(pm.media_file) mediapost is giving me the right items but repeated four times
GROUP_CONCAT(pm.media_type) mediaposttype s giving me the right items but repeated four times
I can put here all tables structures if you need them.
Multiple one-to-many relations JOINed in a query have a multiplicative affect on aggregation results; the standard solution is subqueries:
You can change
GROUP_CONCAT(pm.media_type) mediaposttype
...
LEFT JOIN tb_post_media pm ON pm.media_post = po.id_post
to
pm.mediaposttype
...
LEFT JOIN (
SELECT media_post, GROUP_CONCAT(media_type) AS mediaposttype
FROM tb_post_media
GROUP BY media_post
) AS pm ON pm.media_post = po.id_post
If tb_post_media is very big, and the po.status = 1 condition in the outer query would significantly reduce the results of the subquery, it can be worth replicating the original join within the subquery to filter down it's results.
Similarly, the correlated version I mentioned in the comments can also be more performant if the outer query has relatively few results. (Calculating the GROUP_CONCAT() for each individually can cost less than calculating it for all once if you would only actually using very few of the results of the latter).
or just add DISTINCT to all the group_concat, e.g., GROUP_CONCAT(DISTINCT pm.media_type)
I am running a query on a PHP page that will pull all records from one table, INNER JOIN with two other tables and then list all of the results. However on the second table I only want the most recent record.
Here is my query
SELECT * FROM wn_trailer
INNER JOIN (
SELECT id, trailer_id, trailer_status, trailer_assigned, MAX(last_update), trailer_lat, trailer_long
FROM wn_trailer_history
) AS th ON wn_trailer.id = th.trailer_id
INNER JOIN wn_trailer_status ON wn_trailer_status.id = th.trailer_status
INNER JOIN wn_users ON wn_users.id = th.trailer_assigned
ORDER BY trailer_number ASC
The query runs but returns only the first record.
You want an additional JOIN to bring in the data on the last update date. Also, your subquery needs a GROUP BY:
SELECT *
FROM wn_trailer t INNER JOIN
(SELECT trailer_id, MAX(last_update) as max_last_update
FROM wn_trailer_history
GROUP BY trailer_id
) tht
ON t.id = tht.trailer_id INNER JOIN
wn_trailer_history th
ON th.trailer_id = tht.trailer_id AND
th.last_update = tht.max_last_update INNER JOIN
wn_trailer_status ts
ON ts.id = th.trailer_status INNER JOIN
wn_users u
ON u.id = th.trailer_assigned
ORDER BY trailer_number ASC;
I also added table aliases so the query is easier to write and to read.
I'm trying to left join the second table useri_ban based on the users' ids, with the extra condition: useri_ban.start_ban = max_start.
In order for me to calculate max_start, I have to run the following subquery:
(SELECT MAX(ub.start_ban) AS max_start, user_id FROM useri_ban ub WHERE ub.user_id = useri.id)
Furthermore, in order to add max_start to every row, I need to inner join this subquery's result into the main result. However, it seems that once I apply that join, the subquery is no longer able to access useri.id.
What am I doing wrong?
SELECT
useri.id as id,
useri.email as email,
useri_ban.warning_type_id as warning_type_id,
useri_ban.type as type,
useri.created_at AS created_at
FROM `useri`
inner join
(SELECT MAX(ub.start_ban) AS max_start, user_id FROM useri_ban ub WHERE ub.user_id = useri.id) `temp`
on `useri`.`id` = `temp`.`user_id`
left join `useri_ban` on `useri_ban`.`user_id` = `useri`.`id` and `useri_ban`.`start_ban` = `max_start`
Does this solve your problem? You need GROUP BY in the inner query instead of another join.
SELECT useri.id, useri.email, maxQuery.maxStartBan
FROM useri
INNER JOIN
(
SELECT useri_ban.user_id ubid, MAX(useri_ban.startban) maxStartBan
FROM useri_ban
GROUP BY useri_ban.user_id
) AS maxQuery
ON maxQuery.ubid = useri.id;
I'm trying to select Posts with the associate numbers of Comments and Likes.
This is my query
SELECT `waller_posts`.*,
COUNT(waller_comments.id) AS num_comments,
COUNT(waller_likes.id) AS num_likes
FROM `waller_posts`
LEFT JOIN `waller_comments` ON `waller_comments`.`post_id` = `waller_posts`.`id`
LEFT JOIN `waller_likes` ON `waller_likes`.`post_id` = `waller_posts`.`id`
WHERE `wall_id` = 1
AND `wall_type` = "User"
GROUP BY `waller_posts`.`id`
When I add the second left join in this case of the likes, the results of the num_comments and num_likes came wrong. How can I perform this kind of query?
The query builds up to give you every possible combination of comments and likes on a post.
Probably easiest to just use COUNT(DISTINCT...) :-
SELECT `waller_posts`.*,
COUNT(DISTINCT waller_comments.id) AS num_comments,
COUNT(DISTINCT waller_likes.id) AS num_likes
FROM `waller_posts`
LEFT JOIN `waller_comments` ON `waller_comments`.`post_id` = `waller_posts`.`id`
LEFT JOIN `waller_likes` ON `waller_likes`.`post_id` = `waller_posts`.`id`
WHERE `wall_id` = 1
AND `wall_type` = "User"
GROUP BY `waller_posts`.`id`
Note that your query is relying on a feature of MySQL but which would cause an error in most flavours of SQL. For most flavours of SQL you need to list ALL the non aggregate columns in the GROUP BY clause.
Use Distinct clause because it will display combination of like and comment table data
SELECT `waller_posts`.*,
COUNT(DISTINCT waller_comments.id) AS num_comments,
COUNT(DISTINCT waller_likes.id) AS num_likes
FROM `waller_posts`
LEFT JOIN `waller_comments` ON `waller_comments`.`post_id` = `waller_posts`.`id`
LEFT JOIN `waller_likes` ON `waller_likes`.`post_id` = `waller_posts`.`id`
WHERE `wall_id` = 1
AND `wall_type` = "User"
GROUP BY `waller_posts`.`id`