Deleting MySQL Records Based on a Number - php

I'm using MySQL 5.5. I need to delete records that are higher then 180 from the table and rather then having to do a loop through all records and delete one at a time I wanted to know is there a way to give MySQL a delete command with any field Slide value of 181 or greater?
For example:
conn.execute "DELETE FROM " & CONN_DATABASENAME & ".tbl_course_progress WHERE slide=>'181' AND aid='2'")) & "';"
Thanks,
Frank

You pretty much have it right there
DELETE FROM table WHERE slide >= 181;
Here's a very trivial way to do it in PHP
$slide_id = 181;
$query = sprintf("DELETE FROM table WHERE slide >= %d", $slide_id);
mysql_query($query);

Related

SQL: Calculating a field on the fly - based on entry in related table

Im building a very simple trip-booking system. Im used to Filemaker and love the calculation fields it have. Im new at sql and I dont have the brains to figure out this following 2 things:
I have two tables "Trips" and "Bookings"
Trips: ID,MaxSpots,CurrentSpots
Bookings: ID,FK_ID,Spots
I want my customer to be able to click a row in the "Trips" table and be sent to a page that have a form to enter "Bookings" entries. There will be a hidden field "FK_ID that I want the "ID" from "Trips" to be filled in.
How do I check if entered "Bookings.Spots" is bigger than "Trips.CurrentSpots" and then have it calculate and update Trips.CurrentSpots ?
You can just make a simple querie to compare both of them, just get the ID you need first:
//$conn should be your connection
$query = "SELECT Spots FROM Bookings, Trips WHERE Spots < CurrentSpots and '$ID' = Trips.ID";
$result = mysqli_query($conn, $query);
The result can be read like this if its only one
$value = mysqli_fetch_assoc($result)
Then just get the value from Booking.Spots and update your Trips table however you need with an UPDATE query.

Does MAX(expr) have a limit

I have a table with 25,000 entries and growing. In the code, there is this line
$result = sqlQuery("SELECT MAX(pid)+1 AS pid FROM patient_data");
$newpid = 1;
if ($result['pid'] > 1) $newpid = $result['pid'];
This line returns an error from the database that says duplicate record at 10000.
What this line of code is supposed to be doing is to retrieve the last entry for the pid column and then the next lines of code add one to create the next entry in the table.
From my research MAX() is a summing tool, not a tool used to retrieve the last value entered into a table.
https://dev.mysql.com/doc/refman/5.7/en/group-by-functions.html#function_max
Looking for some clarification on how to use this properly. I can't seem to find a clear answer. Hoping some you more experienced developers can help steer me in the right direction.
Since the table already has the ID column auto incremented and there is only one of those allowed per table in MySQL. I had to resort to a different method.
Decided to go with the get the last record this way.
$result = sqlQuery("SELECT id AS pid FROM patient_data ORDER BY id DESC LIMIT 1");
$newpid = 1;
if ($result['pid'] > 1) $newpid = $result['pid'] + 1; //Changed by Sherwin
setpid($newpid);

How to limit mysql rows to select newest 50 rows

How to limit mysql rows to select newest 50 rows and have a next button such that next 50 rows are selected without knowing the exact number of rows?
I mean there may be an increment in number of rows in table. Well I will explain it clearly: I was developing a web app as my project on document management system using php mysql html. Everything is done set but while retrieving the documents I mean there may be thousands of documents.
All the documents whatever in my info table are retrieving at a time in home page which was not looking good. So I would like to add pages on such that only newest 50 documents are placed in first page next 50 are in second and so on.
But how come I know the exact number of rows every time and I cannot change the code every time a new document added so... numrows may not be useful I think...
Help me out please...
What you are looking for is called pagination, and the easiest way to implement a simple pagination is using LIMIT x , y in your SQL queries.
You don't really need the total ammount of rows you have, you just need two numbers:
The ammount of elemments you have already queried, so you know where you have to continue the next query.
The ammount of elements you want to list each query (for example 50, as you suggested).
Let's say you want to query the first 50 elements, you should insert at the end of your query LIMIT 0,50, after that you'll need to store somewhere the fact that you have already queried 50 elements, so the next time you change the limit to LIMIT 50,50 (starting from element number 50 and query the 50 following elements).
The order depends on the fields you are making when the entries are inserted. Normally you can update your table and add the field created TIMESTAMP DEFAULT CURRENT_TIMESTAMP and then just use ORDER BY created, because from now on your entries will store the exact time they were created in order to look for the most recent ones (If you have an AUTO_INCREMENT id you can look for the greater values aswell).
This could be an example of this system using php and MySQL:
$page = 1;
if(!empty($_GET['page'])) {
$page = filter_input(INPUT_GET, 'page', FILTER_VALIDATE_INT);
if(false === $page) {
$page = 1;
}
}
// set the number of items to display per page
$items_per_page = 50;
// build query
$offset = ($page - 1) * $items_per_page;
$sql = "SELECT * FROM your_table LIMIT " . $offset . "," . $items_per_page;
I found this post really useful when I first try to make this pagination system, so I recommend you to check it out (is the source of the example aswell).
Hope this helped you and sorry I coudn't provide you a better example since I don't have your code.
Search for pagination using php & mysql. That may become handy with your problem.
To limit a mysql query to fetch 50 rows use LIMIT keyword. You may need to find & store the last row id(50th row) so that you can continue with 51th to 100th rows in the next page.
Post what you have done with your code. Please refer to whathaveyoutried[dot]com
check this example from another post https://stackoverflow.com/a/2616715/6257039, you could make and orber by id, or creation_date desc in your query

Move number down if number is missing mysql

I've got a database with question numbers between 1 and 21 all with answers / values etc.
But I want to be able to delete for example question 7.
And if I delete that question that is between other numbers that the question numbers will automatically change from 1-21 to 1-20 instead of 1-6, 8-21.
Is this possible? I tried searching on the web but I couldn't find what I was looking for.
With kind regards,
How do I make this shorter? I know it can be done with innerjoin but I dont know how to correctly use it because the explanations are unclear to me..
`$sql = "DELETE FROM insertquestion
WHERE nummer='".$questionNumber."'";
$deleteFromQuestion = $db->prepare($sql);
$deleteFromQuestion->execute();
$updateSql = "UPDATE insertquestion SET nummer = nummer - 1 WHERE nummer >= '".$questionNumber."'";
$updateSql = $db->prepare($updateSql);
$updateSql->execute();`
and that another time but then with another table (vraag)
You can use Triggers to do this operation ref:
http://www.mysqltutorial.org/mysql-triggers.aspx
or use a update query to set the values (however this method is costly, if tthe number of rows is great in number)
Update table set q_no=q_no-1 where q_no> 5 //(if you delete a question with number 5)
There may be many ways for this requirement. One of them is you can achieve it by trigger. Write an after delete trigger which will update all question numbers of the table.
CREATE TRIGGER tblquestion_delete AFTER DELETE on tblquestion
FOR EACH ROW
BEGIN
UPDATE tblquestion
SET qno = qno - 1
WHERE qno > old.qno;
END
Another way is simply you can write this query immediately after delete query.
$sql = "DELETE FROM insertquestion WHERE number='".$questionNumber."' ;
UPDATE tblquestion SET number = number - 1 WHERE number > '".$questionNumber."' ; ";

mysql - deleting large number of rows with a limit (php nightly cron)

Not sure what the best way to handle this is. For my particular situation I have numerous tables where I want to delete any rows with a timestamp that is greater than 3 months ago... aka only keep records for the last 3 months.
Very simply it would be something like so :
//set binding cutoff timestamp
$binding = array(
'cutoff_time' => strtotime('-3 months')
);
//##run through all the logs and delete anything before the cutoff time
//app
$stmt = $db->prepare("
DELETE
FROM app_logs
WHERE app_logs.timestamp < :cutoff_time
");
$stmt->execute($binding);
//more tables after this
Every table I am going to be deleting from has a timestamp column which is indexed. I am concerned about down the road when the number of rows to delete is large. What would be the best practice to limit the chunks in a loop? All I can think of is doing an initial select to find if there are any rows which need to be deleted then run the delete if there are... repeat until the initial doesn't find any results. This adds in an additional count query for each iteration of the loop.
What is the standard/recommended practice here?
EDIT:
quick writeup of what I was thinking
//set binding cutoff timestamp
$binding = array(
'cutoff_time' => strtotime('-3 months')
);
//set limit value
$binding2 = array(
'limit' => 1000
);
//##run through all the logs and delete anything before the cutoff time
//get the total count
$stmt = $db->prepare("
SELECT
COUNT(*)
FROM app_logs
WHERE app_logs.timestamp < :cutoff_time
");
$stmt->execute($binding);
//get total results count from above
$found_count = $stmt->fetch(PDO::FETCH_COLUMN, 0);
// loop deletes
$stmt = $db->prepare("
DELETE
FROM app_logs
WHERE app_logs.timestamp < :cutoff_time
LIMIT :limit
");
while($found_count > 0)
{
$stmt->execute( array_merge($binding, $binding2) );
$found_count = $found_count - $binding2['limit'];
}
It depends on you table size and its workload so you can try some iterations:
Just delete everything that is older than 3 month. Take a look if it's timing is good enough. Is there performance degradation or table locks? How your app handles period of data deletion?
It case everything is bad consider to delete with 10k limit or so on. Check it as above. Add proper indexes
Even it's still bad, consider selecting PK before delete and than delete on PK with 10k limit and pauses between queries.
Still bad? Add new column "to delete", and perform operation on it with all requirements above.
There is a lot of tricks on for rotating tables. Try something and you will face your needs

Categories