I am new to SQL and I want to fetch 5th highest value without using LIMIT. Here is the code I am trying but it is not working properly. It is showing the 5th lowest value instead of 5th highest value.
SELECT a . * FROM user AS a
WHERE 5 =
(SELECT count( DISTINCT b.id ) FROM user AS b WHERE b.id >= a.id ORDER BY a.id DESC)
Can anyone help me with this?
You could also do:
SET #nth := 5;
SELECT
a.*
FROM jos_modules AS a
WHERE #nth = (
SELECT
COUNT(b.id)
FROM user AS b
WHERE
a.id >= b.id
);
Try this
SELECT a . *
FROM user AS a
WHERE 5 = (
SELECT count( DISTINCT b.id )
FROM user AS b
WHERE a.id >= b.id ORDER BY a.id )
select * from (
select a.* , row_number() over (order by id asc) as RANK
from a ) where RANK=5 ;
If you are using a Teradata DB , you can use qualify statement :
select * from a
qualify row_number () over(order by id asc)=5;
Related
I have the following query:
SELECT a.*
FROM `user_subscription_history` a
LEFT JOIN `transaction` b ON b.tran_date=a.date_time
b.tran_date and a.date_time are both timestamps. I'd like the join to return the closest matching. Currently only returns if matching.
How do i solve this?
You can use ROW_NUMBER() to identify the closest timestamp of another table:
select *
from (
select a.*,
row_number() over(
order by abs(timestampdiff(microsecond, b.tran_date, a.date_time))
) as rn
from user_subscription_history a
cross join `transaction` b
) x
where rn = 1
I want to query above picture.
Left picture is original data, right picture is query data.
select distinct ID, Nickname, Revision
from test_table
This query do not show above picture.
How to avoid duplicate data?
If SQL Server, using window function ROW_NUMBER in subquery:
select t.id, t.nickname, t.revision
from (
select t.*, row_number() over (
partition by t.id order by t.revision desc
) rn
from your_table t
) t
where rn = 1;
Or using TOP with ties with ROW_NUMBER:
select top 1 with ties *
from your_table
order by row_number() over (
partition by id order by revision desc
)
If MySQL:
select t.*
from your_table t
inner join (
select id, MAX(revision) revision
from your_table
group by id
) t1 on t.id = t1.id
and t.revision = t1.revision;
Another trick using TOP 1 with TIES
SELECT Top 1 with ties *
FROM your_table t
Order by row_number() over (partition BY t.id order by t.revision DESC)
select distinct ID, Nickname, MAX(Revision)
from test_table
group by ID
I wrote this:
SELECT DISTINCT CATEGORY FROM T AS T1
CROSS JOIN (SELECT *
FROM T
WHERE T.CATEGORY = T1.CATEGORY
ORDER BY CATEGORY DESC
LIMIT 10)
and I receive this
"Unknown column 'T1.CATEGORY' in 'where clause'".
Why?
Update:
My purpose of this is to get 10 posts of any category.
Because T1 is not visible from within the subquery.
Your JOIN also serves no purpose and/or you probably forgot the JOIN condition.
In JOIN condition should use ON keyword
SELECT DISTINCT CATEGORY FROM T AS T1
CROSS JOIN SELECT * FROM T ON T.CATEGORY = T1.CATEGORY
ORDER BY CATEGORY DESC LIMIT 10;
If you need to get 10 posts of each category you can use a query like this:
SELECT CATEGORY, Post
FROM (
SELECT a.CATEGORY, a.Post, count(*) as rn
FROM #T a
JOIN #T b ON a.CATEGORY = b.CATEGORY AND a.Post >= b.Post
GROUP BY a.CATEGORY, a.Post) dt
WHERE rn < 11;
I have two tables, mytable1 and mytable2. I get results from mytable1 and left join with mytable2.
CREATE TABLE mytable1
( userid int,
type int,
datetime1 DATETIME );
CREATE TABLE mytable2
( userid int,
name varchar(20),
day2 DATE,
time2 TIME );
SELECT x.*, d.name, d.day2, d.time2
FROM ( SELECT * FROM mytable1 WHERE TYPE=1 ORDER BY userid ASC LIMIT 0,50) x
LEFT JOIN mytable2 d
ON x.userid = d.userid
But I need to filter the results, so I will get only results if "mytable2.day2 mytable2.time2" is bigger than 2 days ago. For example let datetime be "2014.03.27 21:00:00". I will get results if mytable2 record is newer than "2014.03.27 21:00:00"
You can check sql fiddle here inital: http://sqlfiddle.com/#!2/a5364/2
My tryout: http://sqlfiddle.com/#!2/a5364/5
Here is what the query will look like :-
select x.*, d.name, d.day2, d.time2
from ( SELECT * FROM mytable1 WHERE type=1 ORDER BY userid ASC LIMIT 0,50) x
left join mytable2 d
on x.userid = d.userid
where ( convert(CONCAT(d.day2,' ',d.time2),datetime) >= SUBDATE(curdate(),INTERVAL 2 DAY))
Use convert() to get the datetime and then use subdate() to find the date before 2 days.
Verify it on the SQL Fiddle you provided.
The question is: if there are no records at all in mytable2 that match a record in mytable1, do you still want to see the mytable1 record? If so, move the condition to the on clause:
select x.*, d.name, d.day2, d.time2
from (SELECT *
FROM mytable1
WHERE type = 1
ORDER BY userid ASC
LIMIT 0, 50
) x left join
mytable2 d
on x.userid = d.userid and
(d.day2 + d.time2) >= DATE_SUB(NOW(), INTERVAL 2 DAY);
Otherwise, you can change the join to an inner join:
select x.*, d.name, d.day2, d.time2
from (SELECT *
FROM mytable1
WHERE type = 1
ORDER BY userid ASC
LIMIT 0, 50
) x join
mytable2 d
on x.userid = d.userid
where (d.day2 + d.time2) >= DATE_SUB(NOW(), INTERVAL 2 DAY);
I have a table with lots of fields in mysql
I need a query to return (in the same raw!) the top last 3 dates (dates can have large gaps between them)
ie:
2012/01/20
2012/01/18
2012/01/12
2012/01/10
2012/01/04
etc...
Any help will be appreciated
I must get them in the same row!
This is the query I am trying to use with no success:
SELECT a.id, a.thedate, b.id AS id1, b.thedate AS thedate1, c.id AS id2, c.thedate as thedate2
FROM mytable AS a INNER JOIN mytable AS b ON a.id = b.id INNER JOIN mytable AS c ON b.id=c.id
WHERE c.thedate = SELECT MAX(thedate)
EDIT :
SELECT group_concat(date) FROM (SELECT date FROM my_table ORDER BY date DESC LIMIT 3) AS temp
Corrected-
SELECT group_concat(date) FROM ( select date from table_name order by date desc limit 3) as a
SELECT GROUP_CONCAT(a.date )
FROM (
SELECT date
FROM my_table
ORDER BY date DESC
LIMIT 3
) AS a