getting same result without using "limit" (MySQL) - mysql

How do i get the same result but without using "limit" in mysql?
SELECT user_id
FROM user_interest
GROUP BY user_id
HAVING COUNT(user_id)
ORDER BY (COUNT(user_id)) DESC
LIMIT 2

Here's some suggestion if you don't want to use limit
select t2.user_id
from (
select row_number() over (order by t1.ct desc) as rn, t1.userid
from (
SELECT user_id, COUNT(user_id) as ct
FROM user_interest
GROUP BY user_id
HAVING COUNT(user_id)
)t1
) as t2 where t2.rn < 3

Related

Table with key is date and serial number

thank you in advance for your help.
I have an SQL table which looks like this.
date and serial number are a composite key together. Meaning there cannot be a tuple with the same date and the same serial_number. Now, I want to get the most recent date (transaction) per serial_number. How can I do this? This is what i tried but it gives me some duplicates.
SELECT DATE_FORMAT(`t1`.date,'%m-%d-%y') as date , `t1`.serial_number
FROM table1 `t1`
WHERE date IN (SELECT MAX(date) FROM table1 GROUP BY serial_number)
order by `t1`.date desc, `t1`.serial_number asc;
You need correlated subquery not only subquery :
SELECT DATE_FORMAT(t.date,'%m-%d-%y') as date, t.serial_number
FROM table1 t
WHERE t.date = (SELECT MAX(t1.date)
FROM table1 t1
WHERE t1.serial_number = t.serial_number
)
order by t.date desc, t.serial_number asc;
You could use a inner join on max_date for serial_number
> SELECT DATE_FORMAT(`t1`.date,'%m-%d-%y') as date
> , `t1`.serial_number FROM `table` `t1` INNER JOIN (
> SELECT serial_number, MAX( DATE_FORMAT(`T`.date,'%m-%d-%y')) max_date
> FROM `table` T
> GROUP BY serial_number ) T ON T.serial_number = `t1`.serial_number AND T.max_date = DATE_FORMAT(`t1`.date,'%m-%d-%y')
>
> order by `t1`.date desc, `t1`.serial_number asc;

SQL Server : how to avoid duplicate data?

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

Group by and get the latest row from each group

I want to return only the newest rows that have a different video_id.
I have been having trouble getting this to work no matter which way I try it... I have done this before and it isn't that difficult but for some reason my particular query will not work.
My table/results:
I have been trying this:
SELECT * FROM user_video_history
WHERE `user_id` = $db_safe_user_id
GROUP BY video_id
ORDER BY `date` DESC LIMIT 3
I have also tried this:
SELECT *
FROM (SELECT *
FROM user_video_history
WHERE `user_id` = $db_safe_user_id
ORDER BY `date` DESC)
GROUP BY `video_id`
ORDER BY `date` DESC
You cannot use select * when you GROUP BY
Try this...
SELECT
A . *
FROM
user_video_history A,
(SELECT
video_id, max(date) maxdate
FROM
user_video_history
WHERE
`user_id` = $db_safe_user_id
GROUP BY video_id) B
where
A.video_id = B.video_id
and A.date = B.maxdate
order by A.date DESC
limit 3
Try this:
SELECT
t1 . *
FROM
user_video_history t1
JOIN
(SELECT
id, MAX(`date`) `date`
FROM
user_video_history
GROUP BY user_id) t2 ON t1.user_id = t2.user_id
AND t1.`date` = t2.`date`
LIMIT 3

MySQL Subquery SUM Limit

I'm trying to do an subquery with SUM() and LIMIT. This works fine with the following code:
SELECT id,
(
SELECT SUM(number)
FROM (
SELECT number
FROM t2
WHERE u_id = '1'
ORDER BY time ASC
LIMIT 30
) AS temp
) AS test
FROM t1
But I want to do it of course dynamically and with the current row ID.
I changed the Query to the following:
SELECT id,
(
SELECT SUM(number)
FROM (
SELECT number
FROM t2
WHERE u_id = p.id
ORDER BY time ASC
LIMIT 30
) AS temp
) AS test
FROM t1 p
This will give the following error:
Unknown column 'p.id' in 'where clause'
Any ideas how to make it working?
Unfortunately, MySQL limits the scope of table aliases. Oracle is another database that does this.
You can phrase your query as a complicated join:
select t1.id, sum(t2.number)
from t1 p join
t2
on p.id = t2.u_id
where 30 >= (select count(*)
from t2 t22
where t22.u_id = t2.u_id and
t22.time <= t2.time
)
group by t1.id;
Or you can do this with variables:
select p.id, sum(number)
from t1 p join
(select t2.*,
#rn := if(#u = t2.u_id, #rn + 1, if((#u := t2.u_id) is not null, 1, 0)) as rn
from t2
(select #u := 0, #rn := 0) vars
order by t2.u_d, time
) t2
on p.id = t2.u_id
where rn <= 30
group by p.id;
why not just change p.id to t1.id? I'm pretty sure it's because you are aliasing t1 in the first select, and it isn't defined in the subquery. Try an inner join instead.
SELECT id,
(
SELECT SUM(number)
FROM (
SELECT number
FROM t2
INNER JOIN t1 p
on u_id = p.id
ORDER BY time ASC
LIMIT 30
) AS temp
) AS test
FROM t1 p
Try this:
SELECT id, temp2.sum_number as test
FROM t1 p
INNER JOIN
(
SELECT SUM(number) as sum_number, temp.u_id
FROM (
SELECT number, u_id
FROM t2
WHERE u_id = p.id
ORDER BY time ASC
LIMIT 30
) AS temp
) AS temp2 ON temp2.u_id = p.id
I moved subqueries in the join part, so i can access to p.id in the subquery.

Return rows around row with a certain value with joins

I have fairly complicated join query from which I want to select a few rows around a result with a certain id.
The query currently looks something like this:
WITH results AS
(
SELECT t1.id, t1.position, t1.points, t2.name
ROW_NUMBER() OVER(ORDER BY t1.position ASC, t1.points DESC) AS rn
FROM Table1 t1
JOIN Table2 t2 ON t1.id = t2.Table1id
/* Several more joins here, some of which limit the result set */
)
SELECT * FROM results
WHERE rn < ( SELECT rn+3 FROM results WHERE id = #someid )
AND rn > ( SELECT rn-3 FROM results WHERE id = #someid )
Is there a better way to solve this? Most of all I'm worried about performance with these multiple calls to a possibly huge CTE.
The query is run on a SQL 2008 server.
Maybe pull the joins out of the CTE.
That way the query optimizer has a chance filter out rows before processing the joins.
WITH results AS
(
SELECT t1.id, t1.position, t1.points
, ROW_NUMBER() OVER(ORDER BY t1.position ASC, t1.points DESC) AS rn
FROM Table1 t1
)
SELECT results.id, results.position, results.points, t2.name
FROM results
JOIN Table2 t2 ON t2.id = results.Table1id
/* Several more joins here */
WHERE rn < ( SELECT rn+3 FROM results WHERE id = #someid )
AND rn > ( SELECT rn-3 FROM results WHERE id = #someid )
You could use another cte to help form the filter:
WITH results AS (
SELECT
t1.id
, t1.position
, t1.points
, t2.name
, ROW_NUMBER() OVER (ORDER BY t1.POSITION ASC, t1.points DESC) AS rn
FROM Table1 t1
JOIN Table2 t2
ON t1.id = t2.Table1id
/* Several more joins here, some of which limit the result set */
),
filter AS (
SELECT
rn
FROM results
WHERE id = #someid
)
SELECT
*
FROM results
WHERE rn < ( SELECT rn + 3 FROM filter )
AND rn > ( SELECT rn - 3 FROM filter )