SQL query to find the greater duplicate row - mysql

I've a table in a DB that looks like this:
TABLE `partecipanti` (
`ID` int(11) NOT NULL,
`Name` varchar(30) DEFAULT NULL,
`Surname` varchar(30) DEFAULT NULL,
`Score2` int(11) DEFAULT NULL,
`Zero1` int(11) DEFAULT '0',
`Zero2` int(11) DEFAULT '0',
`Score1` int(10) NOT NULL DEFAULT '0'
)
And a query that looks like this:
SELECT *,Score1 + Score2 as Total FROM partecipanti
ORDER BY Total DESC,Score2 DESC,Zero2 DESC,Score1 DESC, Zero1 DESC;
Now the thing I'd like to do is : when I've a duplicate record (same name and same surname while the other data including ID are differents) pick the row that has the higher score which is stored in the field Total
I was thinking about a nested query,in the first query I order the data and I group them with GROUP BY, then I select the higher element. Could anyone help me please? Thanks.
EDIT:
If I add the DISTINCT statement the query seems to work , is it ok? Thanks.

You can try to run the following query and find the duplicates with max(id).
SELECT Score1, Score2, COUNT(*), Max(ID) AS dupes
FROM participanti
GROUP BY Total
HAVING (COUNT(*) > 1)

Given score2 can be null, try this:
select
p1.*
from
partecipanti p1
join ( select name, surname, max(score1 + coalesce(score2, 0) ) totalScore from partecipanti group by name, surname) p2 on
p1.Name = p2.Name and
p1.Surname = p2.Surname and
p1.score1 + coalesce(p1.score2, 0) = p2.totalScore

Related

How to select the latest record of each different value of a column

Based on this table:
How can I return the latest record of each different vehicle ( assuming I know the values, but if there is a solution that assumes I don't know them it would be better) so let's say for this particular database it would return those in the red box (column id is A.I.):
i have tried with MAX (id) but for some reason it returns null
Any ideas?
You can select max id from the different value that you are asking. This example works if your id is auto increment and the latest the id inserted the bigger the date.
For example:
create table `car` (
id int(9) not null auto_increment,
`date` varchar(40) default null,
staff varchar(50) default null,
staffindex int(3) default null,
vehicle varchar(50) default null,
vehicleindex int(3) default null,
fuel varchar(30) default null,
km varchar(30) default null,
comments varchar(255) default null,
Primary key id(`id`) );
insert into car values (1,"26/08/2021","Christos","0","ITY-2683","2","50","128.315",""), (2,"27/08/2021","Sotiris","1","IOY-3949","3","65","322.522","car needs cleaning"), (3,"26/08/2021","Vaggelis","0","ITY-2682","2","50","128.315",""),(4,"26/08/2021","Teo","1","YTI-7963","3","65","322.522","car needs cleaning"),(5,"26/08/2021","Christos","0","ITY-2683","2","50","128.315",""), (6,"27/08/2021","Sotiris","1","IOY-3949","3","65","322.522","car needs cleaning"), (7,"26/08/2021","Vaggelis","0","ITY-2682","2","50","128.315",""),(8,"26/08/2021","Teo","1","YTI-7963","3","65","322.522","car needs cleaning");
select * from car;
And for your solution you can use:
select * from car where id in (select max(id) from car group by staff) order by id desc;
I am using MariaDB, the same is for MySQL
You can try something like this.
Select Max(Dates) MaxDate, vehicle From Table1 Group by vehicle
From the above query you will get maxDate for each vehicle, if this is
not your answer then please provide more information what and how you
want to display your records.
Selecting the max date might help you to solve your problem.
SELECT * FROM table
WHERE Dates IN (SELECT max(Dates) FROM table);
How can I return the latest record of each different vehicle
One method is a correlated subquery. Assuming by latest you mean by date:
select t.*
from t
where t.date = (select max(t2.date) from t t2 where t2.vehicle = t.vehicle);
With an index on (vehicle, date), this is probably the most performant solution.
MySQL also lets you use in with tuples:
select t.*
from t
where (t.vehicle, t.date) in (select t2.vehicle, max(t2.date)
from t t2
group by t2.vehicle
);

How to use SET with SELECT DISTINCT

I have a table:
CREATE TABLE `test` (
`id` int(11) NOT NULL,
`pn` varchar(40) NOT NULL,
`price` int(1) NOT NULL,
`company` varchar(30) NOT NULL,
`flag` varchar(1) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
What I want to do is to find cheapest goods (pn) and I've managed to do it:
SELECT DISTINCT min(price), pn, company FROM `test` GROUP BY pn
But how I can also mark cheapest goods with flag. I want for all the results Update tabel, set flag=1.
How to do that? Is it possible to use UPDATE table with SELECT DISTINCT?
Here is a SQL Fiddle:
http://sqlfiddle.com/#!9/ea1b3f/9
First, select distinct with group by is almost never the right thing to do. Presumably, you intend something like:
SELECT min(price), pn, min(company)
FROM `test`
GROUP BY pn;
If you want to set a flag for all the min prices, use a join:
update test t join
(select pn, min(price) as minprice
from test
group by pn
) tt
on t.pn = tt.pn and t.price = tt.minprice
set t.flag = 1;

Insert into with multi select or multi conditions

I have a table that contains many informations:
CREATE TABLE sequences (
`id` INT(11) NOT NULL DEFAULT '0',
`name` TEXT NULL,enter code here
`nbrlsu` BIGINT(20) NULL DEFAULT NULL,
`nbrits` BIGINT(20) NULL DEFAULT NULL,
`nbrco1` BIGINT(20) NULL DEFAULT NULL,
`nbrrcbl` BIGINT(20) NULL DEFAULT NULL,
`nbrmatk` BIGINT(20) NULL DEFAULT NULL,
`nbrsequences` BIGINT(20) NULL DEFAULT NULL,
`parent_id` BIGINT(20) NULL DEFAULT NULL,
PRIMARY KEY (`id`)
);
I want to create a table based on sum of columns in the first table
for exemple I want to know te number of elements that have the same parent_id and has numbersequences>0
and I want to know for each type of sequences the number of rows that contains information:
SELECT parent_id ,
Classification,count(id) as nbrspecies,
SUM(nbrsequences) ,
SUM(nbrco1),
SUM(nbrits),
SUM(nbrlsu),
SUM(nbrrcbl),
SUM(nbrmatk)
FROM dashboard_specimen
GROUP BY parent_id
and I have an other kind of queries:
SELECT parent_id ,
count(id) as co1
FROM dashboard_specimen
WHERE nbrco1>0
GROUP BY parent_id ;
and
SELECT parent_id ,
count(id) as nbrspecies
FROM dashboard_specimen
WHERE nbrsequences>0
GROUP BY parent_id
and other types like this
and my goal in the end is to insert this information into an other table with insert select
like this:
INSERT INTO bold_namestats (id,
name,
numberofstrains,
numberofsequences,
numberofco1,
numberofits,
numberoflsu,
numberofrbcl,
numberofmatk)
SELECT parent_id ,
Classification,
count(id) as nbrspecies,
SUM(nbrsequences) ,
SUM(nbrco1),
SUM(nbrits),
SUM(nbrlsu),
SUM(nbrrcbl),
SUM(nbrmatk)
FROM dashboard_specimen
GROUP BY parent_id
I don't know if there is a simple way to do this with temp tables or something like this
If I understand well, you could do a subquery for each column you want to populate, filtering each subquery for an id.
INSERT INTO bold_namestats (id,
name,
numberofstrains,
numberofsequences,
numberofco1,
numberofits,
numberoflsu,
numberofrbcl,
numberofmatk)
select parent_id, (*select1* where parent_id=...), (*select2* where parent_id=...), ... , (*selectn* where parent_id=...)
from dashboard_specimen
group by parent_id
where select1, select2, ... , selectn are the different queries you have.
Finally I have resolved my problem using join and temp tables
INSERT INTO bold_namestats (_id,numberofstrains, numberofsequences,numberofco1,numberofits,numberoflsu,numberofrbcl,numberofmatk,numberstrainswithco1,numberstrainswithseq)
SELECT a._id ,a.numberofstrains,a.numberofsequences ,a.numberofco1,a.numberofits,a.numberoflsu,a.numberofrbcl,a.numberofmatk,b.numberofstrainswithco1,c.numberofstrainswithseq FROM bold_temp_namestats a left join bold_strainswithco1 b on a._id=b.parent_id left join bold_strainswithseq c on a._id=c.parent_id union
SELECT a._id ,a.numberofstrains,a.numberofsequences ,a.numberofco1,a.numberofits,a.numberoflsu,a.numberofrbcl,a.numberofmatk,b.numberofstrainswithco1,c.numberofstrainswithseq FROM bold_temp_namestats a right join bold_strainswithco1 b on a._id=b.parent_id left join bold_strainswithseq c on a._id=c.parent_id ;
this query is used to replace full outer join so I fill 3 tables with data and after that I insert with joinin result with left and right join and union the result to get full lines in the end

sorting with Order By in mysql

I am using mysql as database and i have a table like the one below.
CREATE TABLE IF NOT EXISTS `logins` (
`id` int(255) NOT NULL AUTO_INCREMENT,
`userid` varchar(255) NOT NULL,
`date` varchar(255) NOT NULL,
`status` varchar(255) NOT NULL,
KEY `id` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=346 ;
I want to sort mysql results with order by.The problem is when i use this sql it takes only the first recod of date. Which is an older date. I want the newest date. last login date of user.
SELECT * FROM `logins` WHERE `status`='valid' GROUP BY `userid` ORDER BY `date` DESC
Any suggestions?
To do this you use a sub query to get the latest record for each user id and then join that to the logins table to get the rest of the details
SELECT logins.*
FROM logins
INNER JOIN
(
SELECT userid, MAX(`date`) AS max_date
FROM `logins`
WHERE `status` = 'valid'
GROUP BY `userid`
) sub0
ON logins.userid = sub0.userid
AND logins.`date` = sub0.max_date
WHERE `status` = 'valid'
You almost had it. Assuming id and userId doesn't evolve from one login to another, asking the MAX date should give you the expected result.
SELECT id, userId, MAX(`date`) AS lastDate, 'valid'
FROM `logins`
WHERE `status`='valid'
GROUP BY `userid`
ORDER BY `lastDate` DESC
Please note that you would need a JOIN if there were data that change between logins in the table.

MySQL query for nested or join

I have such a MYSQL table
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`screen_name` text NOT NULL,
`user_no` int(20) NOT NULL,
`avatar` text NOT NULL,
`name` varchar(50) NOT NULL,
`location` varchar(50) DEFAULT NULL
PRIMARY KEY (`id`)
I need to create an SQL query.
ORDER BY id DESC
GROUP BY screen_name
Get "name" and "screen_name" fields
id between $idmin and $idmax
I will compare the performance of nested query and JOIN query seperately.
Can you propose query words?
Thank you
Edit: For nested query I tried this:
SELECT `name`,`screen_name` FROM `mytable` WHERE `id` IN
(SELECT `id` FROM `mytable` WHERE `id` BETWEEN 100 AND 500 ORDER BY `id` DESC)
GROUP BY `screen_name`
I couldn't write for joined type.
Edit2: Say it I have such rows:
id=1, screen_name=mike, name=uk
id=2, screen_name=albert, name=usa
id=3, screen_name=ash, name=uk
id=4, screen_name=albert, name=new_zelland
I need to get results like this:
id=4
id=3
id=1
Your query should be in this format:
SELECT MAX(id) AS max_id, user_no, screen_name
FROM table_name
WHERE id BETWEEN $idmin AND $idmax
GROUP BY screen_name
ORDER BY MAX(id) DESC;
SQLFIDDLE DEMO HERE
or with sub-query:
SELECT a.id, a.name, a.screen_name
FROM example a
INNER JOIN (SELECT screen_name, MAX(id) id
FROM example
WHERE id BETWEEN 1 AND 4
GROUP BY screen_name
) b
ON a.screen_name = b.screen_name
AND a.id = b.id
ORDER BY a.id DESC;
SQLFIDDLE DEMO HERE