MYSQL DISTINCT and ORDER BY together - mysql

I have a table like the following
item_id position_number position_date
1 9 2013-06-29 15:12:58
2 7 2013-07-25 15:12:58
18 5 2013-07-08 12:07:00
13 9 2013-07-08 12:07:00
I want to get the items group by position_number and order by position_date DESC, so the query will return the following:
item_id position_number position_date
13 9 2013-07-08 12:07:00
2 7 2013-07-25 15:12:58
18 5 2013-07-08 12:07:00
I've been implementing some of the solutions that use DISTINCT and GROUP BY, but not get the desired result.
Does anyone have an idea about how to solved it?

SELECT a.*
FROM tableName a
INNER JOIN
(
SELECT position_number, MAX(position_date) position_date
FROM tableName
GROUP BY position_number
) b ON a.position_number = b.position_number AND
a.position_date = b.position_date
ORDER BY a.position_number DESC
SQLFiddle Demo

Given your example data, this query will return the specified resultset:
SELECT t.item_id
, t.position_number
, t.position_date
FROM ( SELECT MAX(n.item_id) AS max_item_id
FROM mytable n
GROUP BY position_number
) m
JOIN mytable t
ON t.item_id = m.max_item_id
ORDER BY t.position_number DESC
NOTE This is choosing a single item_id for each position_number. This is assuming that a given item_id will appear only once, and have a single position_number. (If an item_id can be associated with multiple postion_number, the query can be tweaked. This is using the MAX() function to choose the item_id with the largest value. (The only example of a row being excluded is item_id=1.)

try this
select * from your_table group by position_number order by position_date DESC
EDIT:
SELECT `item_id`, max(`position_number`) position_number , max(`position_date`) position_date FROM TABLENAME
GROUP BY POSITION_NUMBER
ORDER BY POSITION_DATE DESC
DEMO

Here is SQLFiddle
SELECT * FROM TABLE_NAME
GROUP BY POSITION_NUMBER
ORDER BY POSITION_DATE DESC

Try this code:
SELECT * FROM TABLE_NAME GROUP BY POSITION_NUMBER ORDER BY POSITION_DATE DESC

Use GROUP_BY and either MIN or MAX to decide which date in the group you want to use for sorting.
SELECT * FROM my_table GROUP BY position_number ORDER BY MAX(position_date) DESC;

Related

achieve "order by" before "group by" in mysql

i have a DB with this structure
id, UserID, price, Date
,1, 10.00, 2000-01-01
,1, 25.00 ,2022-02-01
,2, 12.00 ,2000-01-05
,2, 13.00 ,2001-01-05
,2, 24.00 ,2022-01-01
,3, 23.00 ,2022-01-01
i want to show the price for each user based on newest date.
So just 1 row per UserID (latest date)
if we query above table. results need to be like this:
,1, 25.00 ,2022-02-01
,2, 24.00 ,2022-01-01
,3, 23.00 ,2022-01-01
i have tried those 2 commands but they are not working
SELECT UserID,price,Datee FROM (SELECT UserID,price,Datee FROM tbl
ORDER BY UserID ASC,datee DESC) as tb_temp GROUP BY UserID
also this
SELECT UserID,price,max(Datee) FROM tbl Group by UserID ORDER BY UserID ASC,datee DESC
this command show latest date but price is not based on that
so i need something like ORDER BY datee then group by userID or LIMIT 1 per userID
If you're on MySQL 8, the most common way to achieve this is with a window function:
select userid, price, date
from (select *
, row_number() over (partition by userid
order by date desc) as row_priority
from tbl
) subq
where subq.row_priority = 1
Here's a working demo on dbfiddle
You could use a window function to good effect as MarcinJ has done--another approach would be to use a correlated subquery:
SELECT
S1.UserID,
S1.price,
S1.Date
FROM
SampleDetails S1
WHERE
S1.Date = (SELECT MAX(S2.Date) FROM SampleDetails S2 WHERE S2.UserID = S1.UserID GROUP BY S2.UserID);
You can try it out on DB Fiddle.
You could try this, it's not the most efficient because it uses a sub-query:
SELECT t.UserID, t.price, t.Datee
FROM tbl t
JOIN tbl on t.id = (SELECT id FROM tbl WHERE UserID = t.UserID ORDER BY Datee DESC LIMIT 1)
GROUP BY UserID
The idea is to join the table to itself by finding the latest row for the user id.
I made this sql fiddle to test it: http://sqlfiddle.com/#!9/63d495/2

Retrieve the second latest record with same id

From the following four records, I want to select the OwnerId of second-latest record
ItemId OwnerId Date
11477 20981 2013-05-13
11477 1 2013-05-21
11477 21086 2013-05-22 #this is the one I'm talking about
11477 3868 2013-05-24
How to go about it?
This needs ItemID to be specified,
SELECT *
FROM TableName
WHERE ItemID = '11477'
ORDER BY DATE DESC
LIMIT 1,1
SQLFiddle Demo
However, if you don't want to specify the ItemID, and you want to get all second latest record for every ItemID, you can use a correlated subquery to generate a sequence number for every ItemID based on lastest DATE,
SELECT ItemId, OwnerID, Date
FROM
(
SELECT A.ItemId,
A.OwnerId,
A.Date,
(
SELECT COUNT(*)
FROM tableName c
WHERE c.ItemId = a.ItemId AND
c.Date >= a.Date) AS RowNumber
FROM TableName a
) x
WHERE RowNumber = 2
SQLFiddle Demo
select ownerid
from your_table
order by date desc
limit 1, 1
I think you can just to ORDER BY date descending, which will give you an order from newer to older, then LIMIT 1,1 to get only the second result, which should be the one you look for
SELECT *
FROM table
ORDER BY date DESC
LIMIT 1,1

MySQL select top ten records with no duplicate uid

I have the following table (user_record) with millions of rows like this:
no uid s
================
1 a 999
2 b 899
3 c 1234
4 a 1322
5 b 933
-----------------
The uid can be duplicate .What I need is to show the top ten records(need inclued uid and s) with no duplicate uid order by s (desc). I can do this by two steps in the following SQL statements:
SELECT distinct(uid) FROM user_record ORDER BY s DESC LIMIT 10
SELECT uid,s FROM user_record WHERE uid IN(Just Results)
I just wana know is there a bit more efficient way in one statement?
Any help is greatly appreciated.
ps:I also have following the SQL statement:
select * from(select uid,s from user_record order by s desc) as tb group by tb.uid order by tb.s desc limit 10
but it's slow
The simpliest would be by using MAX() to get the highest s for every uid and sorted it based on the highest s.
SELECT uid, MAX(s) max_s
FROM TableName
GROUP BY uid
ORDER BY max_s DESC
LIMIT 10
SQLFiddle Demo
The disadvantage of the query above is that it doesn't handles duplicates if for instance there are multiple uid that have the same s and turn out to be the highest value. If you want to get the highest value s with duplicate, you can do by calculating it on the subquery and joining the result on the original table.
SELECT a.*
FROM tableName a
INNER JOIN
(
SELECT DISTINCT s
FROM TableName
ORDER BY s DESC
LIMIT 10
) b ON a.s = b.s
ORDER BY s DESC

Need Select top 10 people SQL

I need SQL query for MySQL to select top 10 people with most followers
my table
id | user_id | follow_id
1 3 6
2 3 7
3 4 6
4 5 6
5 7 3
6 9 7
From example user with id 6 have 3 time followed , 7->2 and 3->1, so TOP 10 will be
user with id 6,7,3 ...
SELECT `follow_id`, COUNT(1) AS `followers`
FROM `tbl`
GROUP BY `follow_id`
ORDER BY COUNT(1) DESC
LIMIT 10;
You want to use MySQL GROUP BY aggregation funciton
SELECT user_id, COUNT(follow_id) AS total_followers
FROM users
GROUP BY follow_id
ORDER BY total_followers LIMIT 10;
SELECT follow_id,count(id) AS cnt FROM table
GROUP BY follow_id ORDER BY cnt DESC LIMIT 10
You can use
SELECT user_id , COUNT(id) AS count FROM tbl GROUP BY follow_id ORDER BY count DESC LIMIT 10;
You need to group the results by the follow_id and then count how many results are in this group and sort this by the number of results per group in a descending order and then define you want to limit it to only 10 results which can be done by using LIMIT 0,10
The following query works perfectly in MySQL 5
SELECT follow_id, COUNT(follow_id) AS nr
FROM test.testtable
GROUP BY follow_id
ORDER BY nr DESC
LIMIT 0,10
Try some thing like this:
select follow_id
from myTable
group by follow_id
order by count(user_id)
Limit 10
SELECT follow_id,
COUNT(user_id) AS number_of_followers
FROM table
GROUP BY follow_id
ORDER BY number_of_followers DESC
LIMIT 10;

MySQL: Select records where COUNT

I'm trying to select 1000 customers that have placed exactly 1 order. Everything is in the Orders table.
select * from Order having count(CustomerID) = 1 limit 1000
So basically all records that have only one occurence of the CustomerID in the entire table. This returns an empty result set and there are 100,000s in the table.
You need to GROUP in order to (meaningfully) use the HAVING clause. The following works as expected:
SELECT
*
FROM
`Order`
GROUP BY
CustomerID
HAVING
COUNT(CustomerID) = 1
LIMIT 1000
UPDATE
Adding WHERE (see comments):
SELECT
*
FROM
`Order`
WHERE
Language = 'EN'
GROUP BY
CustomerID
HAVING
COUNT(CustomerID) = 1
LIMIT 1000
SELECT * FROM `Order`
GROUP BY CustomerID
HAVING COUNT(CustomerID) = 1
LIMIT 1000
try
select count(CustomerID) as counter ,o.* from Order o
group by CustomerID having counter = 1 limit 1000
Add group by to query for correct output, e.g:
select *
from Order
group by CustomerID
having count(CustomerID) = 1
limit 1000
SELECT CustomerID FROM Order GROUP BY CustomerID HAVING COUNT(*) = 1 LIMIT 1000