delete from database except that filter - mysql

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
)

Related

Joining two columns in mysql

I want to add data from table b in table a but unfortunately full outer join do not work in mysql . I have also tried union but it is throwing errors because my statement has group by and order by keyword
SELECT COUNT( ReviewedBy ) AS TotalReviews, OrganizationId, SUM( Rating ) AS TotalStars, COUNT( Rating ) AS TotalRatings, (
SUM( Rating ) / COUNT( Rating )
) AS AverageRating
FROM `tbl_reviews`
WHERE ReviewType = 'shopper'
AND ReviewFor = 'org'
AND OrganizationId
IN (
SELECT OrganizationId
FROM tbl_organizations
WHERE CategoryID =79
)
GROUP BY OrganizationId
ORDER BY AverageRating DESC
This is what i'm getting from the above statement
I want to get organizationId 21 data in the result but i'm not getting result because it's not present in 'tbl_review' table
click here to see the table b
How can i get Desired result ?
You don't need a FULL, but a LEFT join:
SELECT COUNT( ReviewedBy ) AS TotalReviews, o.OrganizationId,
SUM( Rating ) AS TotalStars, COUNT( Rating ) AS TotalRatings,
(SUM( Rating ) / COUNT( Rating )) AS AverageRating
FROM tbl_organizations AS o
LEFT JOIN `tbl_reviews` AS r
ON o.OrganizationId = r.OrganizationId
AND ReviewType = 'shopper' -- conditions on inner table
AND ReviewFor = 'org' -- must be moved to ON
WHERE CategoryID =79
GROUP BY o.OrganizationId
ORDER BY AverageRating DESC
Why don't you use AVG instead of SUM/COUNT?
Have you tried:
from organization
left outer join tbl_reviews
on organization.ID = tbl_reviews.organization is
for your where clause? I don't think you need a full outer join in this case... A left outer join should do

SQL - Trying to find max count between two tables

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;

Mysql query distinct + multiple

I want to do this query:
SELECT *
FROM user k
INNER JOIN (
SELECT id, tagName, b.guid, name, owner, publicKey
FROM noteTags a
INNER JOIN (
SELECT *
FROM note
ORDER BY guid
LIMIT 0 , 12
)b ON a.guid = b.guid ORDER BY b.id DESC
)l ON k.owner = l.owner
But I want it to return DISTINCT b.guids.
Structure of the tables:
note
|
|=id
|=name
|=guid
|=owner
|=publicKey
noteTags
|
|=guid
|=tagName
user
|
|=owner
|=username
|=auth
Basically I want to select ALL data (with the limit on the deeper inner join) and return DISTINCT guids
Thanks!
Here's my initial answer,
SELECT *
FROM note a
INNER JOIN user b
ON a.owner = b.owner
INNER JOIN notetags c
ON a.guid = b.guid
INNER JOIN
(
SELECT guid, MAX(tagName) maxTag
FROM notetags
GROUP BY guid
) d ON c.guid = d.guid AND
c.tagName = d.maxTag
How about:
SELECT *
FROM user k
INNER JOIN (
SELECT id, tagName, b.guid, name, owner, publicKey
FROM noteTags a
INNER JOIN (
select id, name, MIN(guid) as guid, owner, publicKey
FROM note
GROUP BY guid
LIMIT 0 , 12
)b ON a.guid = b.guid ORDER BY b.id DESC
)l ON k.owner = l.owner

MySQL show the row with the latest Date for each different value in other column?

I'm working with a mysql query that is supposed to select all messages addressed or sent by the user. I need to group all messages with same UID so that I show a single thread for each differente user (this means it should eliminate all messages except the last with same UID). My problem is that I started using GROUP BY to do it but sometimes the row that remains is actually the older message instead of the latest.
This is what I was trying:
SELECT `UID`, `Name`, `Text`, `A`.`Date`
FROM `Users`
INNER JOIN (
(
SELECT *, To_UID AS UID FROM `Messages` WHERE `From_UID` = '$userID' AND `To_UID` != '$userID'
)
UNION ALL
(
SELECT *, From_UID AS UID FROM `Messages` WHERE `To_UID` = '$userID' AND `From_UID` != '$userID'
)
) AS A
ON A.UID = Users.ID
GROUP BY UID // This doesn't work
How can I show only the row with the most resent date per UID?
use DISTINCT and only use ORDER BY date
GROUP BY actually sometimes displays a random row, which isn't always commonly discussed.
you can try some thing like this:
select UID, Name, Text, c.date
from User
inner join (
select if(b.From_UID = '$userID', b.To_UID, b.From_UID) as UID,
*
from Messages as b
inner join(
select if(c.From_UID = '$userID', c.To_UID, c.From_UID) as UID,
max(c.date) as date
from Messages as c
where c.From_UID = '$userID' or c.To_UID = '$userID'
group by UID
) as d on d.date = b.date and d.UID = b.UID
) as e on e.UID = Users.id
)
or create a temp table / stored procedure to make life easier
Temp table
create temp table t
select if(From_UID = '$userID', To_UID, From_UID) as UID, * from Messages
select UID, Name, Text, date
from User
inner join (
select *
from t as t1
inner join(
select
t2.UID,
max(t2.date) as date
from t as t2
group by t2.UID
) as t3 on t3.date = t1.date and t3.UID = t1.UID
) as e on e.UID = Users.id

GROUP_CONCAT multiple values from table

I just added a table which holds a url and description for each item in place. The below query works ok ... but it's only returning the url and I need the desc also. I m not sure how to make this work.
$query_str = "SELECT a.userid, a.cat, a.id, a.name, a.image,
a.desc, a.country, b.user_id, c.username,
c.fbook, d.cat_id,
(
SELECT GROUP_CONCAT(url)
FROM one_add o
WHERE a.id=o.one_id
) AS url,
(
SELECT COUNT(id)
FROM one_msg m
WHERE m.guest_id = ? AND
m.one_id=a.id
) AS count
FROM place a
LEFT OUTER JOIN wait b
ON a.id=b.post_id AND
b.user_id= ?
JOIN users c
ON a.userid=c.id
LEFT JOIN (
SELECT userid, user_id,
GROUP_CONCAT( cat_id ) AS cat_id
FROM user_cat
WHERE userid='$user_id'
GROUP BY user_id
) AS d ON d.userid='$user_id' AND
d.user_id=a.userid
WHERE a.cat != ? ORDER BY a.date desc";
This is what I want to accomplish: desc
You can achibe this by using CONCAT inside GROUP_CONCAT function as:
(SELECT GROUP_CONCAT(CONCAT('',desc,''))
FROM one_add o
WHERE a.id=o.one_id) AS url
full query:
(SELECT COUNT(id) FROM one_msg m WHERE m.guest_id = ? AND m.one_id=a.id ) AS count
FROM place a
LEFT OUTER JOIN wait b ON a.id=b.post_id AND b.user_id= ?
JOIN users c ON a.userid=c.id
LEFT JOIN ( SELECT userid, user_id, GROUP_CONCAT( cat_id ) AS cat_id FROM user_cat WHERE userid='$user_id' GROUP BY user_id ) AS d ON d.userid='$user_id' AND d.user_id=a.userid
WHERE a.cat != ? ORDER BY a.date desc";