Limit number of rows returned ORDER BY - mysql

I want to limit the number of rows returned when using a statement with an ORDER BY clause.
One of my columns has an ID not unique to the row and so appears multiple times. If I use a LIMIT at the end of the statement it would limit the results entirely, not at the SELECT point. The LIMIT might be 3, in which case three rows for each ID would be returned.
id | .........
1 | .........
1 | ........
1 | .......
1 | ......
1 | .....
2 | ....
2 | ...
2 | ..
2 | .
The end of my statement has:
ORDER BY id, date DESC

Here is one method:
select t.*
from table t
where (select count(*)
from table t2
where t2.id = t.id and t2.date >= t.date
) <= 3
order by id, date desc;
This counts the number of dates for an id that are equal to or larger than the date in a row, and only keeps the rows where the count is less than or equal to 3.

Related

SQL - Selecting all or none in a set of rows

I have a table where multiple entries are grouped by having the same number. Each of these rows also have a result.
Example
id 4 | Group 5 | Result 1
id 5 | Group 5 | Result 1
id 6 | Group 6 | Result 0
id 7 | Group 6 | Result 1
How would I go about selecting the highest number group where all their result is the same number?
In otherwords, say I want to get the highest group where result = 1; I would not want group 6 as there is a result is 0, nor would I want any groups older than group 4 as all of group 5 have a result of 1.
There's a couple of different ways to do this. Here's one approach to select the highest group using order by and limit where all results are 1 using max and min:
select grp
from yourtable
group by grp
having max(result) = 1 and min(result) = 1
order by grp desc
limit 1
This is a slightly dierent approach.
SELECT `group` FROM `test`
GROUP BY `group`
HAVING COUNT(`result`)=SUM(`result`) AND SUM(`result`)>0
ORDER BY `group` DESC LIMIT 1;
Check it on SQL Fiddle

SQL display rows with grouping rows with same one column value

I want to grouping rows with same wolumn customer name and also display other rows .I have this table
id || name_customer || date
1 name 1 21/07/2018
2 name 2 22/07/2018
3 name 3 23/07/2018
5 name 1 27/07/2018
So The resulst that I want is :
to order rows by date desc first and grouping by same name customer :
id || name_customer || date
5 name 1 27/07/2018
1 name 1 21/07/2018
3 name 3 23/07/2018
2 name 2 22/07/2018
I tried :
SELECT * FROM my_table
GROUP BY name_customer
order BY date DESC
but it didn't work
Any one can help me please.
It seems you want to sort the customers by their maximum date first and then sort within customer by date again.
As of MySQL 8.0:
select *
from my_table
order by
max(date) over (partition by name_customer) desc,
name_customer,
date desc;
In older versions:
select *
from my_table
order by
(
select max(date)
from my_table m
where m.name_customer = my_table.name_customer
) desc,
name_customer,
date desc;
just use customer name in order by
SELECT * FROM my_table
order BY name_customer,date desc
https://www.db-fiddle.com/f/jzh4cEoYXVKfvs6ZmSVhfG/2
id name_customer date
5 name 1 2018-07-27
1 name 1 2018-07-21
2 name 2 2018-07-22
3 name 3 2018-07-23

How can I select adjacent row in sql when ordered by a different field?

I've got a table of data with the following structure:
id | likes
1 | 2
2 | 5
3 | 2
4 | 6
5 | 2
If want to find the row next to #3 I can use :
SELECT * FROM table WHERE id >= 3 ORDER BY id
However what I want to do is order by table by likes. When the data is ordered by likes it looks like this
id | likes
1 | 2
3 | 2
5 | 2
2 | 5
4 | 6
How can I select the rows before or after a certain id when ordered by likes?
e.g. for id 5, my result would be row id 3 before and row id 2 after.
If likes are unique numbers, following should work.
previous:
SELECT * FROM table WHERE likes < (SELECT likes FROM table WHERE id = ID) ORDER BY likes DESC LIMIT 1
next:
SELECT * FROM table WHERE likes > (SELECT likes FROM table WHERE id = ID) ORDER BY likes ASC LIMIT 1
You may change 1 of them to <= or >= and add WHERE id != ID
Your second table shows wrong ids for the first two rows, by the way.
It should be:
id likes
1 2
3 2
This works in MySQL for me:
Select id, likes from (SELECT id, #rownum:=#rownum+1 AS rownum, likes
FROM table u, (SELECT #rownum:=0) r ORDER BY likes) as derived where
rownum >= 2 and rownum <= 4;
(SELECT id, #rownum:=#rownum+1 AS rownum, likes FROM table u, (SELECT
#rownum:=0) r ORDER BY likes);
The last part tries to simulate the row number, which is missing in MySQL, but available in MSSQL, Oracle and others.

MySql select next lower number without using limit

Is it possible to select the next lower number from a table without using limit.
Eg: If my table had 10, 3, 2 , 1 I'm trying to select * from table where col > 10.
The result I'm expecting is 3. I know I can use limit 1, but can it be done without that?
Try
SELECT MAX(no) no
FROM table1
WHERE no < 10
Output:
| NO |
------
| 3 |
SQLFiddle
Try this query
SELECT
*
FROM
(SELECT
#rid:=#rid+1 as rId,
a.*
FROM
tbl a
JOIN
(SELECT #rid:=0) b
ORDER BY
id DESC)tmp
WHERE rId=2;
SQL FIDDLE:
| RID | ID | TYPE | DETAILS |
------------------------------------
| 2 | 28 | Twitter | #sqlfiddle5 |
Another approach
select a.* from supportContacts a inner join
(select max(id) as id
from supportContacts
where
id in (select id from supportContacts where id not in
(select max(id) from supportContacts)))b
on a.id=b.id
SQL FIDDLE:
| ID | TYPE | DETAILS |
------------------------------
| 28 | Twitter | #sqlfiddle5 |
Alternatively, this query will always get the second highest number based on the inner where clause.
SELECT *
FROM
(
SELECT t.col,
(
SELECT COUNT(distinct t2.col)
FROM tableName t2
WHERE t2.col >= t.col
) as rank
FROM tablename t
WHERE col <= 10
) xx
WHERE rank = 2 -- <<== means second highest
SQLFiddle Demo
SQLFiddle Demo (supports duplicate values)
If you want to get next lower number from table
you can get it with this query:
SELECT distinct col FROM table1 a
WHERE 2 = (SELECT count(DISTINCT(b.col)) FROM table1 b WHERE a.col >= b.col);
later again if you want to get third lower number you can just pass 3 in place of 2 in where clause
again if you want to get second higher number, just change the condition of where clause in inner query with
a.col <= b.col

Select Query to get last 3 calls and mails

I have 2 tables. One of tables has all mails from users and other table has all calls from users.
Table 1
call_id, | call_date | user_id
1 | 10/01/12| 3
2 | 9/01/12 | 3
Table 2
mail_id, | mail_date | user_id
1 | 8/01/12 | 3
2 7/01/12 | 3
I need to get last last 3 calls and mails :
10/01/12 - call
9/01/12 - call
8/01/12 - mail
Assuming MySQL, and for just one User_ID...
SELECT
*
FROM
(
SELECT 'call' AS type, id, call_date AS event_date, user_id FROM table_1
UNION ALL
SELECT 'mail' AS type, id, mail_date AS event_date, user_id FROM table_2
)
data
WHERE
user_id = 3
ORDER BY
event_date DESC
LIMIT
3
EDIT: Ooops, forgot to specify DESC in the ORDER BY, sorry.
Declare #userID int;
SET #userID=3;
select call_id FROM table_1
where user_id=#userID
order by call_date desc limit 2
UNION ALL
select mail_id FROM table_2
where user_id=#userID
order by mail_date desc limit 1