I have a SQL server database and I would like to delete every row except the last 15, but, I need this to be per 'UserID'.
My database contains entries for a number of different users, where their ID is column 'UserID', so I want each user to have 15 entries in the database and the old ones to be removed.
What would the SQL be for this?
Here is an example effort from myself:
$sql = "DELETE FROM SocialSenseTracking WHERE UserID NOT IN (SELECT TOP 15 UserID='$user' FROM SocialSenseTracking ORDER BY UserID DESC)";
You can use a CTE and row_number() for this:
with todelete as (
select sst.*, row_number() over (partition by UserId order by CreatedAt desc) as seqnum
from SocialSenseTracking sst
)
delete from todelete
where seqnum > 15;
You don't specify the column used to determine the most recent records, so I just invented CreatedAt.
Related
Using this query,
SELECT username, MAX(wordpermin) as maxword,date_created FROM user_records where DATE(date_created) = CURDATE() GROUP BY(username) ORDER BY maxword DESC LIMIT 20
I am trying to query a limit of 20 of the top wordpermin by their username and the time created and that by calling date_created in the current 24 hours.
The problem I have is when I have a new high wordpermin. Instead of giving me also the new date_created, it keeps the old value of date_created. I even looked into my database and I made sure I have date_created updated. How can this happen?
I mean, I have two values from different rows.
The following query gives you the last date where a user has the maxword.
Your query would not run when you activated ONLY_FULL_GROUP_BY.
You should always specify for every column which aggregation function you want to use, because SQL rows don't have any order and every column will be selected on its own.
I selected Max (date_created), so that MySQL knows which date to show, because if there were more than one date with the same maximum word, MySQL would show all.
SELECT
u.username, u1.maxword, MAX(u.date_created)
FROM
user_records u
INNER JOIN
(SELECT
username,DATE(date_created) date_created, MAX(wordpermin) AS maxword
FROM
user_records
GROUP BY username,DATE(date_created)) u1 ON u.username = u1.username
AND u.wordpermin = u1.maxword AND Date(u.date_created) = DATE(u1.date_created)
WHERE
DATE(u.date_created) = CURDATE()
GROUP BY (username)
ORDER BY maxword DESC
LIMIT 20;
LIMIT 20
Examole http://sqlfiddle.com/#!9/857355/2
I want to select last 50 rows from MySQL database within column named id which is primary key. Goal is that the rows should be sorted by id in ASC order, that’s why this query isn’t working
SELECT
*
FROM
`table`
ORDER BY id DESC
LIMIT 50;
Also it’s remarkable that rows could be manipulated (deleted) and that’s why following query isn’t working either
SELECT
*
FROM
`table`
WHERE
id > ((SELECT
MAX(id)
FROM
chat) - 50)
ORDER BY id ASC;
Question: How is it possible to retrieve last N rows from MySQL database that can be manipulated and be in ASC order ?
You can do it with a sub-query:
SELECT * FROM
(
SELECT * FROM table ORDER BY id DESC LIMIT 50
) AS sub
ORDER BY id ASC;
This will select the last 50 rows from table, and then order them in ascending order.
SELECT * FROM table ORDER BY id DESC LIMIT 50
save resources make one query, there is no need to make nested queries
SELECT * FROM table ORDER BY id DESC, datechat DESC LIMIT 50
If you have a date field that is storing the date (and time) on which the chat was sent or any field that is filled with incrementally (order by DESC) or de-incrementally (order by ASC) data per row put it as second column on which the data should be ordered.
That's what worked for me!!!! Hope it will help!!!!
Use it to retrieve last n rows from mysql
Select * from tbl order by id desc limit 10;
use limit according to N value.
if anyone need this
you can change this into
SELECT
*
FROM
`table`
WHERE
id > ((SELECT
MAX(id)
FROM
chat) - 50)
ORDER BY id ASC;
into
SELECT
*
FROM
`table`
WHERE
id > (SELECT MAX(id)- 50 FROM chat)
ORDER BY id ASC;
select * from Table ORDER BY id LIMIT 30
Notes:
* id should be unique.
* You can control the numbers of rows returned by replacing the 30 in the query
Let's say I have a table with the following columns:
p_id
userid
points
Let's say these columns have over 5000 records. So we actually have users with points. Each user has an unique row for their point record. Imagine that every user can get points on the website by clicking somewhere. When they click I update the database with the points they get.
So we have a table with over 5000 records of people who have points, right? Now I would like to order them by their points (descending), so the user with the most point will be at the top of the page if I run a MySQL query.
I could do that by simply running a query like this:
SELECT `p_id` FROM `point_table` ORDER BY `points` DESC
This query would give me all the records in a descending order by points.
Okay, here my problem comes, now (when it is ordered) I would like to display each user which place are they actually. So I'd like to give each user something like this: "You are 623 of 5374 users". The problem is that I cannot specify that "623" number.
I would like to run a query which is order the table by points it should "search" or count the row number, where their records are and than return that value to me.
Can anyone help me how to build a query for this? It would be a really big help. Thank you.
This answer should work for you:
SET #rank=0;
SELECT #rank:=#rank+1 AS rank, p_id FROM point_table ORDER BY points DESC;
Update: You might also want to consider to calculate the rank when updating the points and saving it to an additional column in the same table. That way you can also select a single user and know his rank. It depends on your use cases what makes more sense and performs better.
Update: The final solution we worked out in the comments looked like this:
SELECT
rank, p_id
FROM
(SELECT
#rank:=#rank+1 AS rank, p_id, userid
FROM
point_table, (SELECT #rank := 0) r
ORDER BY points DESC
) t
WHERE userid = intval($sessionuserid);
Row number after order by
SELECT ( #rank:=#rank + 1) AS rank, m.* from
(
SELECT a.p_id, a.userid
FROM (SELECT #rank := 0) r, point_table a
ORDER BY a.points DESC
) m
For some reason the accepted answer doesn't work for me properly - it completely ignores "ORDER BY" statement, sorting by id (primary key)
What I did instead is:
SET #rn=0;
CREATE TEMPORARY TABLE tmp SELECT * FROM point_table ORDER BY points DESC;
SELECT #rn:=#rn+1 AS rank, tmp.* FROM tmp;
Add a new column for position to the table. Run a cron job regularly which gets all the table rows ordered by points and then update the table with the positions in a while loop.
How can I select a single random entry from a MySQL database using PHP?
I want to select the Author, AuthorText, and Date?
SELECT Author, AuthorText, Date FROM table ORDER BY RAND() LIMIT 1
Take a look to this interesting article:
“Do not use ORDER BY RAND()” or “How to get random rows from table?”
ORDER BY rand() LIMIT 1
will sort all the rows in the table, which can be extremely slow.
Better solution : say your table has the usual primary key auto-increment field, generate a rendom number between min(id) and max(id) and select the closest id.
It will not be as random as a "true" random selection, because a id after a large hole of deleted ids will have a higher probability of being chosen. But it will take 50 µs instead of 2 seconds if your table is large...
SET #t = (SELECT FLOOR(a + (b-a)*rand()) FROM (SELECT min(id) as a, max(id) as b FROM table)
SELECT * FROM table WHERE id>#t ORDER BY id LIMIT 1;
You can order by a random & restrict to 1 row as follows:
select
author, authortext, date
from bookstable
order by rand()
limit 1
i want something like this:
SELECT DISTINCT ID from copies WHERE timestamp < 1229444506 ORDER BY CID
the problem is that this one only return ID and i need CID and other columns in the table.
It may be that this is totally wrong for other reason aswell, so i will explain what i need.
I have a table that "record" every row-change in my maintable. This so in the future i will be able to go back in time and see how the main table looked like a certain date in time.
So what i need is a query that ORDER all rows BY CID, WHERE timestamp < 1229444506, AND then DISCTINCT them by ID.
I want to the query to return the first row by ID, when ordered by CID newest first.
Ive tried to get this working with different methods but no luck.
Any suggestions?
I am not sure if I got it correctly, but what about creating a subquery that will just select the columns? You wrote:
"I want to the query to return the first row by ID, when ordered by CID newest first."
So, let's make a subquery:
SELECT id, max(cid) as maxcid FROM copies WHERE timestamp < XX group by id
This will give you the relationship id <=> the CID you want. And now join it:
SELECT copies.* FROM copies, (SELECT id, max(cid) as maxcid FROM copies WHERE timestamp < xxx group by id) x
WHERE copies.id=x.id AND copies.cid=x.maxcid;
SELECT * FROM copies WHERE timestamp < 1229444506 GROUP BY ID ORDER BY CID DESC;
EDIT:
SELECT * FROM copies WHERE timestamp < 1229444506 GROUP BY ID ORDER BY CID;
You can also try:
SELECT * FROM copies WHERE timestamp < 1229444506 GROUP BY ID ASC ORDER BY CID;
Or:
SELECT * FROM copies WHERE timestamp < 1229444506 GROUP BY ID DESC ORDER BY CID;
Does it work?
how can your database know which rows to append to your distinct column? say you haveː
id | name
---+-----
1 | a
1 | b
now the hypothetical query: SELECT DISTINCT id, name FROM table. which name do you expect to show up in your result? a or b?
if that's not a problem you can group your result in mysql by id, but it’s unspecified which name you'll get
SELECT `id`, `name` FROM `copies` WHERE `timestamp` > 123456789 GROUP BY `id` ORDER BY `cid` DESC