Hi i know this question has been asked before but i'm asking it differently, what i want is to reset the auto_increment column, after deleting a row in a table. if i have table with 51 rows and i delete row 48, i want row 49 to reset to 48,50 to 49 etc.
i have tried using alter table but that insert data where the row was deleted, i want something that will shift the order.
-- Table structure for table torrents
CREATE TABLE IF NOT EXISTS `torrents` (
`ID` int(11) NOT NULL AUTO_INCREMENT,
`Title` varchar(250) NOT NULL,
`Kat_Link` varchar(250) NOT NULL,
`Tpb_Link` varchar(250) NOT NULL,
`Lime_Link` varchar(250) NOT NULL,
`ImgUrl` varchar(250) NOT NULL,
PRIMARY KEY (`ID`)
) ENGINE=InnoDB;
what i want is to run a select from table where ID = $id lmit 8 if the ID doesn't exists i get less than 8 rows.
It's going to be difficult to achieve that just use limit with your select statement, what you want is to get number of rows(e.g 8 rows) by ID, if that ID doesn't exists, your select statement is going to give you less rows than you want.
SELECT * FROM table LIMIT $r,$s // here you are guaranteed that you'll get 8 rows all the time
If you insist on filling the gap, there's a way around to shift the later records on the table you provided.
SQL = "UPDATE torrents SET ID=ID-1 WHERE ID > 48";
To alter the table in order to reset the AI,
ALTER TABLE `torrents ` AUTO_INCREMENT =51
Try a trigger, I haven't touched a MySQL database in a long time, so the syntax below might be incorrect, but it presents the idea of what it's trying to achieve well enough.
CREATE OR REPLACE updateTableTrigger
AFTER delete on 'torrents'
FOR EACH ROW
BEGIN
SET #id = old.ID
UPDATE torrents SET ID = (#id-1) WHERE ID > #id;
END
Essentially it just deducts the row's ID by one after the deleted row.
So if you delete row with an ID of 5 it'll affect all rows after row of ID 5 and decrement their values by 1 to fill in the gap.
Related
I have a table where I log members.
There are 1,486,044 records here.
SELECT * FROM `user_log` WHERE user = '1554143' order by id desc
However, this query takes 5 seconds. What do you recommend ?
Table construction below;
CREATE TABLE IF NOT EXISTS `user_log` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user` int(11) NOT NULL,
`operation_detail` varchar(100) NOT NULL,
`ip_adress` varchar(50) NOT NULL,
`l_date` datetime NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
COMMIT;
For this query:
SELECT * FROM `user_log` WHERE user = 1554143 order by id desc
You want an index on (user, id desc).
Note that I removed the single quotes around the filtering value for user, since this column is a number. This does not necessarily speeds things up, but is cleaner.
Also: select * is not a good practice, and not good for performance. You should enumerate the columns you want in the resultset (if you don't need them all, do not select them all). If you want all columns, since your table has not a lot of columns, you might want to try a covering index on all 5 columns, like: (user, id desc, operation_detail, ip_adress, l_date).
In addition to the option of creating an index on (user, id), which has already been mentioned, a likely better option is to convert the table to InnoDB as create an index only on (user).
Well, I have this attendance system who mark an attendance every day, well what I am looking is for a restriction other than PHP code like a restriction that can restrict users to enter duplicate record over time.
For e.g I have already marked my attendance .myself
DATE 22-05-2018 and trackingid = 1
if I try to insert mark attendance one more time it should not insert the statement.
It can be done via php and its a long code and i mean like it is possible but is there any way around with MySQL , through which we can make 2 columns unique if they both already exist just dont let user insert .
Use unique_index on your columns
ALTER TABLE `tablename` ADD UNIQUE `unique_index`(`columnOneName`, `columnTwoName`);
You can also use the following like sql while creating your table:-
CREATE TABLE `tableName` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`columnOne` int(11) DEFAULT NULL,
`columnTwo` int(11) DEFAULT NULL,
`columnThree` varchar(128),
PRIMARY KEY (`id`),
UNIQUE KEY `columnOne_columnTwo_unique_index` (`id_box_elements`,`id_router`)
);
I have a php script that logs inputs from a form into a mysql database table. I'm looking for a way to insert this data untill 3 rows are created, after which it has to update the existing rows so that the first one updates to the new input, the second one to the former first input and the third one to the former second input.
Table:
CREATE TABLE IF NOT EXISTS inputlog (
id int(11) NOT NULL auto_increment,
userid int(11) NOT NULL default '0',
name text,
value text,
PRIMARY KEY (id)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;`
For the first three rows i use:
insert into inputlog (userid,name,value) values('$userid','$name','$value')
After that is has to become:
update inputlog set value = '$value' where userid = '$userid' and name = '$name'
where it has to update all the successive rows.
How can i accomplish this?
Too long for comments, so...
Looks like you want to have only 3 rows in your table because you want the data to be sorted by the id. So id=1 will be the latest value, then id=2 and finally id=3.
In short, do not do that, the id field can be any value. Do not code for that. The danger is if you use the id in another table as a foreign key, you will loose referential integrity. What I propose is:
Add an timestamp column for each row.
Every time you insert a new value, set the timestamp column to NOW()
When selecting, sort on the timestamp and limit to 3 results
If you MUST have only 3 rows, you can then delete the row except for the 3 most recent timestamps.
But... if you must do that...
perform a SELECT with the first 2 lines
truncate the table (delete all rows)
insert the new line, then the 2 stored lines
You will then ahve your 3 rows in the order you want. But without seeing the entire reasoning for your application, my "spider sense" tells me you will hit a wall later on...
And check the comments for other things to worry about.
I want to set two columns in MySql as auto increment (int)
S.NO Q_id
I want to set both auto increased.
How can I do this?
In same table you can't use two auto increments fields. You can create a integer field and add value +=1 in php
...
$row_last_id++;
INSERT INTO ... values(id, $row_last_id)
Updated Try this: It can be possible with use of MyISAM storage engine try Below Code
CREATE TABLE invoices ( S_NO mediumint unsigned NOT NULL auto_increment, Q_id mediumint unsigned NOT NULL, date date NOT NULL, PRIMARY KEY (S_NO,Q_id) ) COMMENT='' ENGINE='MyISAM'
Is it possible to make a script without else/if that deletes the oldest row for a user if the new row is the 4 row for that specific user?
I have a table called points_history. Fields are:
date(datetime),
fk_player_id(int),
points(int)
Here is my insert:
mysqli_query($mysqli,"INSERT INTO points_history (date,fk_player_id,points) VALUES (NOW(),$player,$points)");
The reason for this taht I want to be able to go back in the players history and check points, but only the last 3 points and don't want a table with a million of rows.
Can it be done in one sql query?
Hoping for help and thanks in advance :-)
This is quite easy to do if you add a primary key to your table points_history.
Part 1:
Use the following script to add a primary key called points_history_id to your table:
ALTER TABLE points_history RENAME TO points_history_old;
CREATE TABLE points_history
(
`points_history_id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT,
`date` datetime NOT NULL,
`fk_player_id` int(11) NOT NULL,
`points` int(11) NOT NULL,
PRIMARY KEY (`points_history_id`)
);
INSERT INTO points_history (date, fk_player_id, points)
SELECT date, fk_player_id, points
FROM points_history_old;
-- Drop table if migration succeeded (up to you)
-- DROP TABLE points_history_old;
This needs to be run only once!
Part 2:
Now you can use the following SQL script to add a new record and delete the outdated:
-- First insert the new record
INSERT INTO points_history (date,fk_player_id,points)
VALUES (NOW(),:player,:points);
-- Create temporary table with records to keep
CREATE TEMPORARY TABLE to_keep AS
(
SELECT points_history_id
FROM points_history
WHERE fk_player_id = :player
ORDER BY date DESC
LIMIT 3
);
SET SQL_SAFE_UPDATES = 0;
-- Delete all records not in table to_keep
DELETE FROM points_history
WHERE points_history_id NOT IN (SELECT points_history_id FROM to_keep);
SET SQL_SAFE_UPDATES = 1;
-- Drop temporary table
DROP TEMPORARY TABLE to_keep;
If you use a database supporting transactions, I strongly recommend to wrap this script in a transaction. I tested it on MySQL 5.5.29 and it runs fine.