SQL - Trying to find max count between two tables - mysql

So I have two tables, STOPS_AT and POINT_OF_INTEREST, which are like this:
STOPS_AT[Route_ID, Stop_ID]
and
POINT_OF_INTEREST[Stop_ID, Name, Category]
Now I am trying to select the Route_ID who has the most number of stops at a point of interest. In other words, the route who has the most number of stops, who also appear in the POINT_OF_INTEREST table. I have tried the following:
select Route_ID
from (select Route_ID, count(POINT_OF_INTEREST.Stop_ID) as cnt
from STOPS_AT R
group by Route_ID
) rc join
(select max(cnt) as maxcnt
from (select Route_ID, count(POINT_OF_INTEREST.Stop_ID) as cnt
from STOPS_AT
group by Route_ID
) rc
) m
on rc.cnt = m.maxcnt;
However this doesn't seem to work, saying it is unaware of the POINT_OF_INTEREST table?

Your query doesn't join to the point_of_interest table -- that's why you're receiving the error. You are trying to count a field you are not selecting from.
If you don't need to worry about ties, one easy way would be to use limit:
select route_id
from (
select sa.route_id, count(*) cnt
from stops_at sa
join point_of_interest poi on sa.route_id = poi.route_id
group by sa.route_id
) t
order by cnt desc
limit 1
If ties are a concern, then you can alter your query using the above:
select Route_ID
from (
select sa.route_id, count(*) cnt
from stops_at sa
join point_of_interest poi on sa.route_id = poi.route_id
group by sa.route_id
) rc join
(select max(cnt) as maxcnt
from (
select sa.route_id, count(*) cnt
from stops_at sa
join point_of_interest poi on sa.route_id = poi.route_id
group by sa.route_id
) rc
) m
on rc.cnt = m.maxcnt;

Related

delete from database except that filter

I have a database where people via a command sends information and its stored in the database. The same person can have many reports per day and the next query shows only the latest:
SELECT
r1.id,
r1.nickname,
r1.fecha,
r1.bestia1,
r1.bestia2,
r1.bestia3,
r1.bestia4,
r1.bestia5
FROM
reporte AS r1
INNER JOIN
( SELECT
nickname,
MAX(fecha) AS max_date
FROM
reporte
GROUP BY
nickname ) AS latests_reports ON latests_reports.nickname = r1.nickname AND latests_reports.max_date = r1.fecha
ORDER BY
r1.fecha DESC
But now I want to delete all the records except the records returned from the previous query, how can I do it?
Ideally you'd do this as a set of steps, but it may be possible to single-step it by:
DELETE FROM reporte
WHERE id not in
(
SELECT a.id FROM(
SELECT r1.id
FROM reporte AS r1
INNER JOIN ( SELECT nickname, MAX(fecha) AS max_date
FROM reporte GROUP BY nickname ) AS latests_reports
ON latests_reports.nickname =
r1.nickname AND latests_reports.max_date = r1.fecha
) a
)
You need the a.id query in there otherwise MySQL will complain that it can't update the reporte table
As separate steps:
CREATE TABLE to_keep AS
SELECT r1.id
FROM reporte AS r1
INNER JOIN
( SELECT nickname, MAX(fecha) AS max_date FROM reporte GROUP BY nickname ) AS latests_reports
ON
latests_reports.nickname = r1.nickname AND
latests_reports.max_date = r1.fecha
DELETE r.* FROM reporte r LEFT JOIN to_keep k ON r.id = k.id WHERE k.id IS NULL
DROP TABLE to_keep
EDIT: I have updated the query from EXITS() to NOT EXISTS()
You want to delete all records except the records your query listed. This is your query :
:
DELETE FROM Reporte WHERE NOT EXISTS
(
SELECT 1 FROM
(
SELECT r1.id,
FROM reporte AS r1
INNER JOIN ( SELECT nickname, MAX(fecha) AS max_date FROM reporte GROUP BY nickname ) AS latests_reports
ON latests_reports.nickname = r1.nickname
AND latests_reports.max_date = r1.fecha
) r WHERE Reporte.Id= r.Id
)

SQL: Conditional Insert with order by

Hi I have this item about insert if not exists here. One of the things I want to know about is if I want to get the latest items from CompResults by using order by ResultDate, to be inserted to Competitors table, how should I do it?
INSERT Competitors (cName)
SELECT DISTINCT Name
FROM CompResults cr
WHERE
NOT EXISTS (SELECT * FROM Competitors c
WHERE cr.Name = c.cName) ORDER BY cr.ResultsDate DESC
An error happens: ORDER BY items must appear in the select list if SELECT DISTINCT is specified.
Hi you have to use order by fields in select statement I think You are using sql server
so You can use sub query
INSERT Competitors (cName)
select Name
from (
SELECT cr.Name,max(cr.ResultDate)
FROM CompResults cr
WHERE NOT EXISTS (SELECT * FROM Competitors c
WHERE cr.Name = c.cName) group BY cr.name) as t order by ResultDate
Use Row_Number to get the latest record for each Item
Insert into Competitors(col1,col2..)
Select col1,col2,..
(
Select row_number()Over(partition by Name order by ResultDate desc) Rn, *
From CompResults cr
NOT EXISTS (SELECT 1 FROM Competitors c
WHERE cr.Name = c.cName)
) a
Where Rn = 1
Also you can as the below:
INSERT Competitors (cName)
SELECT
A.Name
FROM
CompResults A INNER JOIN
(
SELECT
CR.Name,
MAX(CR.ResultsDate) MaxResultsDate
FROM
CompResults CR
) B ON A.Name = B.Name AND A.ResultsDate = B.MaxResultsDate
WHERE
NOT EXISTS (SELECT 1 FROM Competitors c
WHERE c.cName = A.Name)

MySQL - Get Distinct Primary Col Table Row Order By Foreign Key Table

The title may be confusing, here is my schema
and here is the result of my query
how can i remove duplicates and just get the values highlighted, i am trying to order by message time
Regards
The following syntax will work in both SQL Server and MySQL:
SELECT c.ContactID, c.Name, m.Text, m.Messagetime
FROM Contacts c INNER JOIN
Messages m
ON c.ContactID = m.ContactID
WHERE NOT EXISTS (select 1
from messages m2
where m2.ContactId = m.ContactId and
m2.MessageTime > m.MessageTime
)
ORDER BY m.MessageTime desc;
Note that if you have duplicate most recent message times, then all will be returned.
One way in SQL-Server is using a ranking function like ROW_NUMBER:
WITH CTE AS
(
SELECT c.ContactID, c.Name, m.Text, m.Messagetime,
RN = ROW_NUMBER() OVER (PARTITION BY c.ContactID
ORDER BY m.MessageTime DESC)
FROM dbo.Contacts c
INNER JOIN Messages m ON c.ContactID = m.ContactID
)
SELECT ContadctId, Name, Text, Messagetime
FROM CTE
WHERE RN = 1

Modifying MYSQL query to get a JOIN between two tables

I'm breaking my head trying to modify this query(thx sgeddes) in order to
get at result not only from db_events.events fields, instead join it with some db_system.devices fields
SELECT e.*
FROM db_events.events e
JOIN (
SELECT Max(id) MaxId, device_id
FROM db_events.events
GROUP BY device_id ) e2 on e.Id = e2.MaxId AND e.device_id = e2.device_id
WHERE e.device_id IN (
SELECT device_id
FROM db_system.devices
WHERE vendor = 1)
ORDER BY e.id DESC
How can I get it without repeat the subquery:
SELECT *
FROM db_system.devices
WHERE vendor = 1
I need get db_system.devices.brand and db_system.devices.model joined with final results, and
I tried to modify it step to step, I tried with temporary tables, I suspect it should be something simple, but I have not been able to do it, of course thank you very much...
is this what you want?
SELECT e.*, a.*
FROM db_events.events e
INNER JOIN
(
SELECT Max(id) MaxId, device_id
FROM db_events.events
GROUP BY device_id
) e2 on e.Id = e2.MaxId AND
e.device_id = e2.device_id
INNER JOIN db_system.devices a
ON e.device_id = a.device_id AND
a.vendor = 1
ORDER BY e.id DESC
the condition a.vendor = 1 can also be moved on WHERE clause and the result is still the same since you are using INNER JOIN
SELECT ....
FROM .... JOIN ....
WHERE a.vendor = 1
ORDER BY ...

SQL Query with Joins Counting multiple Results Per Record Ordering By Count

I have a table called Request.
Other tables are linked to the Request table through a request id.
There is a TwitterTweet table and a FacebookPost table.
So a single request can have 50 TwitterTweets and/or 20 FacebookPosts or any amount of Tweets/Posts
We can add them together for a total count of 70.
I'm trying to create a query that could tell me what is the request with the highest total count.
I know this is wrong:
(I attempted to just order them by the counts within the TwitterTweet, but it would not let me do an OUTER JOIN which I thought
would bring back the Count.count column. It forced me to do a Left Join for it to compile. My Logic was to do a join so
that the results were calculated for each row by the requestid)
SELECT r1.`id` AS requestid, r1 . *
FROM `Request` AS r1
LEFT JOIN
(SELECT COUNT( * ) AS count, rid
FROM
((SELECT `TwitterTweet`.`id` AS `smid` , `TwitterTweet`.`requestid` AS rid
FROM `TwitterTweet`
WHERE `TwitterTweet`.`requestid` = requestid
AND `TwitterTweet`.`active` =1) AS talias
)) AS Count ON ( Count.rid = requestid )
ORDER BY Count.count
*When I tried to add in the Facebook side it would not compile any more
(The concept is that the results are added from TwitterTweet with the results from FacebookPost
that are attached to the specific requestid which would give us a count. The entire result
set should be ordered by that count)
SELECT r1.`id` AS requestid, r1 . *
FROM `Request` AS r1
LEFT JOIN
(SELECT COUNT( * ) AS count, rid
FROM
((SELECT `TwitterTweet`.`id` AS `smid` , `TwitterTweet`.`requestid` AS rid
FROM `TwitterTweet`
WHERE `TwitterTweet`.`requestid` = requestid
AND `TwitterTweet`.`active` =1 ) AS talias
UNION All
(SELECT `FacebookPost`.`id` AS `smid`, `FacebookPost`.`requestid` AS rid
FROM `FacebookPost`
WHERE `FacebookPost`.`requestid` = requestid
AND `FacebookPost`.`active` = 1) as falias
)) AS Count ON ( Count.rid = requestid )
ORDER BY Count.count
I updated the Query with an attempt to add an alias:
SELECT rid, SUM(count) total_count
FROM
(
(SELECT COUNT(*) AS count, r.rid
FROM request r
JOIN TwitterTweet tt
ON r.id = tt.requestid
WHERE tt.active = 1
GROUP BY r.rid) AS twitter
UNION ALL
(SELECT COUNT(*) AS count, r.rid
FROM request r
JOIN FacebookPost fp
ON r.id = fp.requestid
WHERE fp.active = 1
GROUP BY r.rid ) AS fbook
)
GROUP BY rid
ORDER BY SUM(count) DESC
I made another adjustment to give the middle subquery an alias, but now I only get one row returned with a zero in the rid column and 5686 in the total_count column...the 5686 might be all of the results.
SELECT counts.rid, SUM(count) total_count
FROM
(
SELECT COUNT(*) AS count, r.requestid AS rid
FROM request r
JOIN TwitterTweet tt
ON r.id = tt.requestid
WHERE tt.active = 1
GROUP BY r.requestid
UNION ALL
SELECT COUNT(*) AS count, r.requestid AS rid
FROM request r
JOIN FacebookPost fp
ON r.id = fp.requestid
WHERE fp.active = 1
GROUP BY r.requestid
) AS counts
GROUP BY counts.rid
ORDER BY SUM(count) DESC
Got it!!!
Thanks for your help guys, I had to remove those joins on the request:
SELECT counts.rid, SUM(count) total_count
FROM
(
SELECT COUNT(*) AS count, tt.requestid AS rid
FROM TwitterTweet tt
WHERE tt.active = 1
GROUP BY tt.requestid
UNION ALL
SELECT COUNT(*) AS count, fp.requestid AS rid
FROM FacebookPost fp
WHERE fp.active = 1
GROUP BY fp.requestid
) AS counts
GROUP BY counts.rid
ORDER BY SUM(count) DESC
SELECT id, SUM(count) total_count
FROM
(
SELECT COUNT(*) AS count, r.id
FROM request r
JOIN TwitterTweet tt
ON r.id = tt.requestid
WHERE tt.active = 1
GROUP BY r.id
UNION ALL
SELECT COUNT(*) AS count, r.id
FROM request r
JOIN FacebookPost fp
ON r.id = fp.requestid
WHERE fp.active = 1
GROUP BY r.id
) sub
GROUP BY id
ORDER BY SUM(count) DESC
;