MySQL query with GROUP BY and JOIN - mysql

Good afternoon,
I'm trying to get some information from my MySQL database and I'm having problems because I'm not able to have the information needed. I have tried a lot of different approaches and none of them have worked. I hope you can find something because I'm very close to find the solution but something is missing:
MySQL query:
SELECT b.id, b.tipo_perfil, round(avg(b.edad)), COUNT(c.zona), c.zona
FROM analizador_datos_usuario AS a
INNER JOIN analizador_datos_perfil AS b ON (a.id_usuario = b.id_perfil)
INNER JOIN analizador_datos_perfil_historial AS c ON (b.id = c.id_perfil)
WHERE a.id_usuario=21
GROUP BY b.tipo_perfil, c.zona
ORDER BY b.tipo_perfil ASC, count(c.zona) DESC
This query gives me the following information:
Table (in red it's what I need):
Kind regards,

try that :
SELECT b.tipo_perfil, round(avg(b.edad)), COUNT(distinct c.zona), group_concat(distinct b.id separator ' ') as id_list, group_concat(distinct c.zona separator ' ') as zona_list
FROM analizador_datos_usuario AS a
INNER JOIN analizador_datos_perfil AS b ON (a.id_usuario = b.id_perfil)
INNER JOIN analizador_datos_perfil_historial AS c ON (b.id = c.id_perfil)
WHERE a.id_usuario=21
GROUP BY b.tipo_perfil
ORDER BY b.tipo_perfil ASC, count(distinct c.zona) DESC

I think you are getting result what is displayed and you want result which is in red colour.
Try this modified query:-
SELECT b.id, b.tipo_perfil, round(avg(b.edad)), COUNT(c.zona) counted_zone, c.zona
FROM analizador_datos_usuario AS a
INNER JOIN analizador_datos_perfil AS b ON (a.id_usuario = b.id_perfil)
INNER JOIN analizador_datos_perfil_historial AS c ON (b.id = c.id_perfil)
WHERE a.id_usuario=21
GROUP BY b.tipo_perfil, c.zona
Having MAX(counted_zone)
ORDER BY b.tipo_perfil ASC, counted_zone DESC

Related

Group concat Query Performance

I have one query which almost took 22 second to populate data.
SELECT
TP.*,
GROUP_CONCAT(DISTINCT TS.`subject_name`) AS subjects,
GROUP_CONCAT(DISTINCT TC.`class_name`) AS classes,
GROUP_CONCAT(DISTINCT TT.`tution_name`) AS tution_type,
GROUP_CONCAT(DISTINCT TL.`name`) AS locations
FROM `tutor_profile` TP
LEFT JOIN `tutor_to_subject` TTS ON TP.`tutor_id`=TTS.`tutor`
LEFT JOIN `tutor_subjects` TS ON TS.`subject_id`=TTS.`subject`
LEFT JOIN `tutor_to_class` TTC ON TP.`tutor_id`=TTC.`tutor`
LEFT JOIN `tutor_classes` TC ON TC.`class_id`=TTC.`class`
LEFT JOIN `tutor_to_tution_type` TTTT ON TP.`tutor_id`=TTTT.`tutor`
LEFT JOIN `tution_types` TT ON TT.`tution_id`=TTTT.`tution_type`
LEFT JOIN `tutor_to_locality` TTL ON TP.`tutor_id`=TTL.`tutor`
LEFT JOIN `tutor_locality` TL ON TL.`id`=TTL.`locality`
WHERE 1=1 AND TP.`status` = 1
GROUP BY TP.`tutor_id`
ORDER BY TP.`date_added` DESC LIMIT 0 , 25
is there anyway to improve its performance?
You may try to use correlated subqueries in the output list instead of JOIN and GROUP BY:
SELECT
TP.*,
( SELECT GROUP_CONCAT(DISTINCT TS.`subject_name`)
FROM `tutor_to_subject` TTS
LEFT JOIN `tutor_subjects` TS ON TS.`subject_id`=TTS.`subject`
WHERE TP.`tutor_id`=TTS.`tutor` ) AS subjects,
-- the same for another output columns
FROM `tutor_profile` TP
WHERE 1=1 AND TP.`status` = 1
ORDER BY TP.`date_added` DESC LIMIT 0 , 25
Replace these
GROUP_CONCAT(DISTINCT TS.`subject_name`) AS subjects,
LEFT JOIN `tutor_to_subject` TTS ON TP.`tutor_id`=TTS.`tutor`
LEFT JOIN `tutor_subjects` TS ON TS.`subject_id`=TTS.`subject`
with
( SELECT GROUP_CONCAT(DISTINCT TS.`subject_name`
FROM `tutor_to_subject` TTS
JOIN `tutor_subjects` TS ON TS.`subject_id` = TTS.`subject`
WHERE TP.`tutor_id` = TTS.`tutor`
) AS subjects,
and toss the JOIN for TS. Do likewise for the other 3 group_concat + Left join.
For many-to-many tables, improve the indexes:
CREATE TABLE tutor_to_subject
tutor_id ...,
subject_id ...,
PRIMARY KEY(tutor_id, subject_id),
INDEX(subject_id)
) ENGINE=InnoDB;
More discussion: Many:many mapping
Also, get rid of the GROUP BY since it should not longer be needed.
And add
INDEX(status, date_added)

Combine data with same id in one column

I have this problem. I need to combine data with the same id in one column. The data are separated with ','. I use group_concat but the result is that it combines all. What I need is for example:
But the result is:
my code
SELECT A.bookId,A.bookDate, A.serviceDate, A.bookTime,A.status, GROUP_CONCAT(C.serviceItemId
SEPARATOR ',') AS Servis, B.custId, B.custFname, B.custLname,B.custContact, B.custEmail, B.gender
FROM booking A
JOIN booking_service C on A.bookId = C.bookId
JOIN customer B ON B.custId =
A.cust_fk WHERE A.cust_fk = 4
ORDER BY A.bookId
Can someone help me?
Why not group_concat the values in a sub-query and then join it to your main result set:
SELECT A.bookId,
A.bookDate,
A.serviceDate,
A.bookTime,
A.status,
d.Servis,
B.custId,
B.custFname,
B.custLname,
B.custContact,
B.custEmail,
B.gender
FROM (
SELECT bookId,
GROUP_CONCAT(serviceItemId SEPARATOR ',') AS Servis
FROM booking_service
GROUP BY bookId
) d
JOIN booking A ON a.bookID = d.bookID
JOIN booking_service C on A.bookId = C.bookId
JOIN customer B ON B.custId = A.cust_fk WHERE A.cust_fk = 4
ORDER BY A.bookId
You need to use GROUP BY with GROUP_CONCAT if you want to limit the results to, for example, a single bookId.

MySQL - Using desc on Group by

I have this query and I would like to use an order by desc on the avg :
select Nomcircuit, avg(Monuments.NBETOILE) as TotalEtoiles from Circuits
inner join CircuitsMonuments on Circuits.Idcircuit = CircuitsMonuments.Idcircuit
inner join Monuments on Monuments.Idmonument = CircuitsMonuments.Idmonument
group by Nomcircuit;
I've tried several things but it just doesn't seem to work.
Just do as you suggested:
SELECT Nomcircuit,
AVG(Monuments.NBETOILE) AS TotalEtoiles
FROM Circuits
INNER JOIN CircuitsMonuments
ON Circuits.Idcircuit = CircuitsMonuments.Idcircuit
INNER JOIN Monuments
ON Monuments.Idmonument = CircuitsMonuments.Idmonument
GROUP BY Nomcircuit
ORDER BY TotalEtoiles DESC

MySQL Lowercase Returned Value Or Entire Result

I have the below SQL query and it will return a group_name along with a list of departments for that group. I was able to lowercase the departments returned, but I can't figure out how to lowercase the group name as well.
Also, instead of lowercasing each returned column is there perhaps a way to lowercase the entire result in one swoop?
SELECT sg.group_name,A.dept_name
FROM `sys_groups` `sg`
INNER JOIN (SELECT gda.group_id,
GROUP_CONCAT(LOWER(sd.dept_name) ORDER BY `dept_name`
SEPARATOR '|'
) `dept_name`
FROM `group_dept_access` `gda`
INNER JOIN `sys_department` `sd`
ON gda.dept_id = sd.dept_id
GROUP BY gda.group_id) AS `A`
ON sg.group_id = A.group_id
Thank you in advance!
Try this:
SELECT LOWER(sg.group_name) group_name, LOWER(A.dept_name) dept_name
FROM sys_groups sg
INNER JOIN (SELECT gda.group_id,
GROUP_CONCAT(sd.dept_name ORDER BY dept_name SEPARATOR '|') dept_name
FROM group_dept_access gda
INNER JOIN sys_department sd ON gda.dept_id = sd.dept_id
GROUP BY gda.group_id
) AS A ON sg.group_id = A.group_id

how to append html to the sql query

i have a sql query, i want to append the html in it and return the resultset into single cell below is my query
SELECT TOP (#TOP) C.Title FROM CrossArticle_Article C
INNER JOIN CrossArticle_ArticleToCategory A2C
ON C.Id = A2C.ArticleId
INNER JOIN CrossArticle_Category CC
ON A2C.CategoryId = CC.Id
INNER JOIN crossarticle_url CU
ON C.Id = CU.articleid
WHERE CC.Id = #CategoryID
AND CC.PortalId = 6
GROUP BY C.TITLE, CU.URL, C.PublishDate
ORDER BY C.PublishDate DESC
currently it will display in row, i want in single cell with html appended to it.
like below <li><span><a href='+CU.URL+'>C.Title</a></span></li>
Please reply if anyone have any idea
As for the how...
SELECT TOP(#TOP) '<li><span><a href=''' + CU.URL + '''>' + C.Title + '</a></span></li>'
FROM...
As for the Why... You might be better-off building this in your mark-up...not sure what your requirements may be, but blending your data layer with your presentation layer can have some drawbacks.
SELECT TOP (#TOP)
'<li><span>'+C.Title+'</span></li>' AS TheColumn
FROM
CrossArticle_Article C INNER JOIN
CrossArticle_ArticleToCategory A2C ON
C.Id=A2C.ArticleId
INNER JOIN
CrossArticle_Category CC ON
A2C.CategoryId=CC.Id
INNER JOIN
crossarticle_url CU ON
C.Id=CU.articleid
WHERE
CC.Id=#CategoryID
AND CC.PortalId=6
GROUP BY
C.TITLE,
CU.URL,
C.PublishDate
ORDER BY
C.PublishDate DESC