How to select rows which have the biggest value of a column? - mysql

I don't know if my title is understandable or not, may be someone can help edit my title?
All I want to do is, for example:
I have a table like this
Engineering appears 5 times with different article_category_abbr, and I want to select only one row with the biggest value of num.
Here, it will be Engineering-ENG-192, and Geriatrics&Gerontology will be Geriatrics&Gerontology-CLM-26
But I don't know how to do it on the whole table using mysql

Join your table to a subquery which finds the greatest num value for each sc group.
SELECT t1.*
FROM yourTable t1
INNER JOIN
(
SELECT sc, MAX(num) AS max_num
FROM yourTable
GROUP BY sc
) t2
ON t1.sc = t2.sc AND
t1.num = t2.max_num;

You can have a subquery that gets the largest value for each sc and the resulting rows will then be joined with the table itself based from two columns - sc and num.
SELECT a.*
FROM tableName a
INNER JOIN
(
SELECT sc, MAX(num) AS Num
FROM tableName
GROUP BY sc
) b ON a.sc = b.sc
AND a.num = b.num
Here's a Demo

USE MAX function and GROUP BY like this. Here is more information.
SELECT myID, classTitle, subField, MAX(score) FROM myTable GROUP BY myID, classTitle, subField

Related

Merge rows in mysql based on condition

I am trying to merge the rows based on condition in mysql.
I have table as shown below :
Looking merge the row 1 into row 2 (where the attendance count is larger)
and need to shown the result as :
I was trying to divide the dataset into 2 parts using the below query
select
a.student_id,a.school_id,a.name,a.grant,a.classification,a.original_classification,,a.consent_type
from (
select * from school_temp where original_classification='all' and availability='implicit')a
join(select * from school_temp where original_classification!='all' and availability!='implicit')b
on a.student_id = b.student_id and a.school_id=b.school_id and a.name=b.name
But unable to merge the rows and get total attendance count .
Please help me ,i am badly stuck in this
Split this into two queries that you combine with UNION.
The first joins the implicit row with the row with the highest attendance among the explicit rows for each student. See Retrieving the last record in each group - MySQL for how that works. Use SUM(attendance_count) to combine the attendances.
The second query in the UNION gets all the rows that don't have the highest attendance.
WITH explicit as (
SELECT *
FROM school_temp
WHERE original_classification!='all' and availability!='implicit'
)
SELECT a.student_id, a.school_id, a.name, SUM(attendance_count) AS attendance_count,
b.grant, b.classification, b.original_classification, b.consent_type
FROM school_temp AS a
JOIN (
SELECT t1.*
FROM explicit AS t1
JOIN (
SELECT student_id, school_id, name, MAX(attendance_count) AS max_attendance
FROM explicit AS t2
GROUP BY student_id, school_id, name
) AS t2 ON t1.student_id = t2.student_id AND t1.school_id = t2.school_id AND t1.name = t2.name AND t1.attendance_count = t2.max_attendance
) AS b ON a.student_id = b.student_id and a.school_id=b.school_id and a.name=b.name
WHERE a.original_classication = 'all' AND a.availability = 'implicit'
UNION ALL
SELECT t1.*
FROM explicit AS t1
JOIN (
SELECT student_id, school_id, name, MAX(attendance_count) AS max_attendance
FROM explicit AS t2
GROUP BY student_id, school_id, name
) AS t2 ON t1.student_id = t2.student_id AND t1.school_id = t2.school_id AND t1.name = t2.name AND t1.attendance_count < t2.max_attendance
I've used a CTE to give a name to the subquery that gets all the explicit rows. If you're using MySQL 5.x, you'll need to replace explicit with that subquery throughout the query. Or you could define it as a view.

SQL Select two records if they have certain time difference of column A and have same column B value

I have 14000 records in my sql table. They have columns ID, test_subject_id and date_created. I want to fetch all the records that have been created within a time difference of 3 minutes(difference in date_created values) and both records should have the same test_subject_id.
You should use a self join, I assume inner join is what will work for you:
SELECT a.ID, a.date_created, b.ID, b.date_created
FROM accounts a
INNER JOIN accounts b
ON a.test_subject_id = b.test_subject_id
AND TIMESTAMPDIFF(MINUTE,a.date_created,b.date_created) = 3
Note: TIMESTAMPDIFF is used assuming date_created has type datetime, details here.
You can use EXISTS:
SELECT t1.*
FROM tablename t1
WHERE EXISTS (
SELECT 1
FROM tablename t2
WHERE t2.test_subject_id = t1.test_subject_id
AND ABS(TIMESTAMPDIFF(SECOND, t1.date_created, t2.date_created)) <= 180
)
ORDER BY t1.test_subject_id, t1.date_created;

MySQL take rows and override ones without user_id

I have table like this one:
I would like to all rows, but if there is user_id 5 if this case, override other rows which have no user_id.
I tried both with MAX(user_id) and GROUP BY country_name, but it still returns, wrong results.
Final result I'm expecting:
Try this;)
select t1.*
from yourtable t1
inner join (
select max(user_id) as user_id, country_name from yourtable group by country_name
) t2 on t1.country_name = t2.country_name and t1.user_id = t2.user_id
This is just a solution based on your sample data. If you have a variety of user_id, it should be more different.
As of SQL Select only rows with Max Value on a Column you can easily get rows with max value on a column by using both MAX(column) and GROUP BY other_column in one statement.
But if you want to select other columns too, you have to this in a subquery like in the following example:
SELECT a.*
FROM YourTable a
INNER JOIN (
SELECT country_name, MAX(user_id) user_id
FROM YourTable
GROUP BY country_name
) b ON a.country_name = b.country_name AND a.user_id = b.user_id

subquery that uses a value from the outer query in the where caluse

I wanna run a subquery that uses the value of the outer query in its where clause. Here's and example of what I wanna do:
SELECT * FROM `tbl1`
WHERE `tbl1`.`max_count` < (
SELECT COUNT(*) rc FROM `tbl2`
WHERE `tbl2`.`id` = `tbl1`.`id
)
There is tbl1 with a column named max_count, and there is tbl2 with rows referring to a row in tbl1(many-to-one relationship). What I wanna do is select rows in tbl1 where the number of rows in tbl2 referencing it is less than the max_count value of that row. But I'm pretty sure that what I wrote here, ain't gonna cut it. Any ideas?
Thanks a lot
try this -
SELECT * FROM `tbl1` t1
WHERE t1.`max_count` < (
SELECT COUNT(*) FROM `tbl2` t2
WHERE t2.`id` = t1.`id`
)
try using JOIN.
SELECT DISTINCT a.*
FROM tb1 a
INNER JOIN
(
SELECT id, COUNT(*) totalCount
FROM tbl2
GROUP BY id
) b ON a.ID = b.ID
WHERE a.max_count < b.totalCount
As an alternate solution, it's probably easier to just use a LEFT JOIN with HAVING than a subquery;
SELECT tbl1.*, COUNT(tbl2.id) current_count
FROM tbl1
LEFT JOIN tbl2
ON tbl1.id=tbl2.id
GROUP BY tbl1.id
HAVING COUNT(tbl2.id) < max_count
An SQLfiddle to test with.
Note that the GROUP BY in this case is a MySQL only thing, normally you'd need to GROUP BY every selected field in tbl1 even if tbl1.id is known to be unique per row.

need to show only the duplicate value in sql

i have table as
id----name----roll-----class
1----ram-------1-----2
2----shyam-----2-----3
3----ram-------1-----3
4----shyam-----2-----3
5----ram-------1-----2
6----hari------1-----5
i need to find the the duplicate row only that have common name, roll, class. so the expected result for me is.
id----name----roll-----class
1----ram-------1-------2
2----shyam-----2-------3
4----shyam-----2-------3
5----ram-------1-------2
i tried to get from the query below but here only one field is supported. i need all three field common. Please do help me in this. thanks
SELECT *
FROM table
WHERE tablefield IN (
SELECT tablefield
FROM table
GROUP BY tablefield
HAVING (COUNT(tablefield ) > 1)
)
You can use count() over().
select id, name, roll, class
from (select id, name, roll, class,
count(*) over(partition by name, roll, class) as c
from YourTable) as T
where c > 1
order by id
https://data.stackexchange.com/stackoverflow/query/63720/duplicates
this will retun only the duplicate entry one time:
select t.id, t.name, t.roll, t.class
from table t
inner join table t1
on t.id<t1.id
and t.name=t1.name
and t.roll = t1.roll
and t.class=t1.class
this will return what you require:
select distinct t.id, t.name, t.roll, t.class
from table t
inner join table t1
on t.name=t1.name
and t.roll = t1.roll
and t.class=t1.class
I'd suggest something like this
SELECT A.* FROM
Table A LEFT OUTER JOIN Table B
ON A.Id <> B.Id AND A.Name = B.Name AND A.Roll = B.Roll AND A.Class = B.Class
WHERE B.Id IS NOT NULL
Something like that should work (I did not test though):
select a1.*
from table a1, a2
where (a1.id != a2.id)
and (a1.name == a2.name)
and (a1.roll== a2.roll)
and (a1.class== a2.class);
It seems there are several proprosals here. If it is a query that you'll use in your code, beware of the cost of the queries. Try an 'explain' with your database.