Order using count from another table - mysql

Hi I need to Order using count from another table. i found this great example, im using it as model for a query i need. SQL - How To Order Using Count From Another Table
The model im using for query is:
SELECT bloggers.*, COUNT(post_id) AS post_count
FROM bloggers LEFT JOIN blogger_posts
ON bloggers.blogger_id = blogger_posts.blogger_id
GROUP BY bloggers.blogger_id
ORDER BY post_count
But i have a syntax problem in mine, i guess, im trying to replace the next query, with the one that counts another table... but i cant manage to do it. Original query:
$res3=$db->execute_query("select id,scode,sname from ".TABLE_PREFIX."states where ccode=? order by sname asc",array($country));
Trying to replace with this query..
$res3=$db->execute_query("select ".TABLE_PREFIX."states.* , COUNT(".TABLE_PREFIX."items.state) AS state_count FROM ".TABLE_PREFIX."states LEFT JOIN ".TABLE_PREFIX."items ON ".TABLE_PREFIX."states.id = ".TABLE_PREFIX."items.state GROUP BY ".TABLE_PREFIX."states.id ORDER BY state_count DESC",array($country));

Try this:
$res3=$db->execute_query("select a.* , COUNT(b.state) AS state_count FROM states a
LEFT JOIN items b ON a.id = b.state
GROUP BY a.id
ORDER BY state_count DESC",array($country));

Related

Working with SELECT and SUB SELECT in MySQL

I have a question about a SQL, I have never worked with the select sub and I ended up getting lost with it.
Meu SQL:
SELECT CLI.id, CLI.nome, CLI.senha, CLI.email, CLI.cpf, CLI.celular, CLI.data_nasc, CLI.genero, CLI.data_cadastro, CLI.status, CLI.id_socket, ATEN.mensagem, ARQ.nome AS foto, ATEN.data_mensagem
FROM ut_clientes AS CLI
LEFT JOIN ut_arquivos AS ARQ ON (ARQ.id_tipo = CLI.id AND ARQ.tipo = "ut_clientes")
INNER JOIN ut_atendimentos AS ATEN ON (ATEN.id_usuario_envio = CLI.id)
WHERE ATEN.id_usuario_envio != 59163
GROUP BY CLI.id
ORDER BY ATEN.data_mensagem
DESC
Well, what I would like to do is group the messages according to the customer ID and bring only the last message recorded in the database according to the data_mensagem.
I have tried in many ways but always the last one that is displayed is the first message inserted in DB.
If anyone can help me, I'll be grateful. Thank you guys!
This may help you... I am using a join to a pre-query (PQ alias). This query just goes to your messages and grabs the client ID and the most recent based on the MAX(). By doing the group by here, it will at most return 1 record per client. I also have the WHERE clause to exclude the one ID you listed.
From THAT result, you do a simple join to the rest of your query.
SELECT
CLI.id,
CLI.nome,
CLI.senha,
CLI.email,
CLI.cpf,
CLI.celular,
CLI.data_nasc,
CLI.genero,
CLI.data_cadastro,
CLI.status,
CLI.id_socket,
ATEN.mensagem,
ARQ.nome AS foto,
PQ.data_mensagem
FROM
ut_clientes AS CLI
LEFT JOIN ut_arquivos AS ARQ
ON CLI.id = ARQ.id_tipo
AND ARQ.tipo = "ut_clientes"
INNER JOIN
( select
ATEN.id_usuario_envio,
MAX( ATEN.data_mensagem ) as MostRecentMsg
from
ut_atendimentos AS ATEN
where
ATEN.id_usuario_envio != 59163
group by
ATEN.id_usuario_envio ) PQ
ON CLI.id = PQ.id_usuario_envio
GROUP BY
CLI.id
ORDER BY
PQ.data_mensagem DESC

Join another table in this sql query

I'm using this one to get related softwares based on their keywords. Now I want to add one more condition that is in another table called software_status having software_id. I found this query on SO, so I can't understand it and can't edit it further.
SELECT softwares.*, count(DISTINCT similar.kid) as shared_tags
FROM softwares
INNER JOIN ( keywords_softwares AS this_software INNER JOIN keywords_softwares AS similar USING (kid) ) ON similar.sid = softwares.id
WHERE this_software.sid=:id
AND softwares.id != this_software.sid
AND (softwares.subcategory = :subcatid or softwares.category = :catid)
GROUP BY softwares.id
ORDER BY shared_tags DESC LIMIT 10

Creating a subquery in Access

I am attempting to create a subquery in Access but I am receiving an error stating that one record can be returned by this subquery. I am wanting to find the top 10 companies that have the most pets then I want to know the name of those pets. I have never created a subquery before so I am not sure where I am going wrong. Here is what I have:
SELECT TOP 10 dbo_tGovenrnmentRegulatoryAgency.GovernmentRegulatoryAgency
(SELECT dbo_tPet.Pet
FROM dbo_tPet)
FROM dbo_tPet INNER JOIN dbo_tGovenrnmentRegulatoryAgency ON
dbo_tPet.GovernmentRegulatoryAgencyID =
dbo_tGovenrnmentRegulatoryAgency.GovernmentRegulatoryAgencyID
GROUP BY dbo_tGovenrnmentRegulatoryAgency.GovernmentRegulatoryAgency
ORDER BY Count(dbo_tPet.PetID) DESC;
Consider this solution, requiring a subquery in the WHERE IN () clause:
SELECT t1.GovernmentRegulatoryAgency, dbo_tPet.Pet,
FROM dbo_tPet
INNER JOIN dbo_tGovenrnmentRegulatoryAgency t1 ON
dbo_tPet.GovernmentRegulatoryAgencyID = t1.GovernmentRegulatoryAgencyID
WHERE t1.GovernmentRegulatoryAgency IN
(SELECT TOP 10 t2.GovernmentRegulatoryAgency
FROM dbo_tPet
INNER JOIN dbo_tGovenrnmentRegulatoryAgency t2 ON
dbo_tPet.GovernmentRegulatoryAgencyID = t2.GovernmentRegulatoryAgencyID
GROUP BY t2.GovernmentRegulatoryAgency
ORDER BY Count(dbo_tPet.Pet) DESC);
Table aliases are not needed but I include them for demonstration.
This should hopefully do it:
SELECT a.GovernmentRegulatoryAgency, t.NumOfPets
FROM dbo_tGovenrnmentRegulatoryAgency a
INNER JOIN (
SELECT TOP 10 p.GovernmentRegulatoryAgencyID, COUNT(p.PetID) AS NumOfPets
FROM dbo_tPet p
GROUP BY p.GovernmentRegulatoryAgencyID
ORDER BY COUNT(p.PetID) DESC
) t
ON a.GovernmentRegulatoryAgencyID = t.GovernmentRegulatoryAgencyID
In a nutshell, first get the nested query sorted, identifying what the relevant agencies are, then inner join back to the agency table to get the detail of the agencies so picked.

GROUP BY not sorting properly when using joins

I want to see only one record from the joined table fr_movements with the newest sched_date yet I am always getting the oldedst sched_date. Since the ORDER BY sorts by the sched_date and I am grouping by the people.ID I am getting only one record from fr_movements as expected, just the wrong one.
SELECT `fr_movements`.`ID`, fr_movements_list.movement_type,
fr_movements.sched_date, fr_movements.comp_date, people.firstname, people.lastname
FROM fr_movements
LEFT JOIN people ON people.ID = fr_movements.`people_id`
LEFT JOIN fr_movements_list ON (fr_movements.move_type_id = fr_movements_list.ID)
WHERE fr_movements.org_id = 25 AND fr_movements.move_type_id IN (54,53,52,51,50,55)
GROUP BY people.ID
ORDER BY people.org_name, fr_movements.sched_date ASC
Anybody know how to do this properly?
as #bluefeet mentioned
you are using GROUP BY incorrectly. GROUP BY is supposed to be used with an aggregate function
You need to put all columns after GROUP BY, but it is complicated. I think DISTINCT might help you. like this:
SELECT *
FROM
(
SELECT DISTINCT people.org_name, `fr_movements`.`ID`, fr_movements_list.movement_type,
fr_movements.sched_date, fr_movements.comp_date, people.firstname, people.lastname
FROM fr_movements
LEFT JOIN people ON people.ID = fr_movements.`people_id`
LEFT JOIN fr_movements_list ON (fr_movements.move_type_id = fr_movements_list.ID)
WHERE fr_movements.org_id = 25
AND fr_movements.move_type_id IN (54,53,52,51,50,55)
) x
ORDER BY org_name, sched_date ASC
If not works, would you post your data & schema into sqlfiddle? That makes us happy.

MySQL views cannot have subquery in from, and don't maintain order. How can I create a view from this query?

I'm essentially trying to obtain a resultset with each employee's current title. I'd like to create a view from this for later use, but I find I'm being stumped, and likely missing a simple solution. Here's the query in question, and thanks in advance!
select * from
(SELECT
appointment.employee_id,
title.`name` as title_name
FROM
appointment
INNER JOIN appointment_title ON appointment.id = appointment_title.appointment_id
INNER JOIN title ON appointment_title.title_id = title.id
order by appointment_title.effective_date DESC) tmp group by employee_id
Updated:
SELECT
appointment.employee_id ,
( SELECT title.`name`
FROM appointment_title
INNER JOIN title
ON appointment_title.title_id = title.id
WHERE appointment.id = appointment_title.appointment_id
ORDER BY appointment_title.effective_date DESC
LIMIT 1
) AS title_name
FROM appointment
GROUP BY appointment.employee_id
Another option is to break up the query into two views. The first view will contain the derived table subquery, and the second will simply select from that one:
CREATE VIEW vwEmployee_Inner AS
SELECT
appointment.employee_id,
title.`name` as title_name
FROM
appointment
INNER JOIN appointment_title ON appointment.id = appointment_title.appointment_id
INNER JOIN title ON appointment_title.title_id = title.id
order by appointment_title.effective_date DESC
And then your original view becomes:
CREATE VIEW vwEmployee AS
SELECT * FROM vwEmployee_Inner GROUP BY employee_id