Calculating values from previous rows in a table with SQL - php

I am learning basic PHP and SQL (using PHPmy admin) and I am having trouble understanding how to handle values from previous rows to calculate data in a new row in the table.
How would I calculate values in a row based on the previously entered row? For example, I want to have each row:
1. Auto create rows until Col A ID = 20
2. Col B – Auto add 1 month to previous row date
3. Col D – Previous row value minus payment(Col C)
Do I use PHP or sql? How would I set it out? Please be gentle I am still very new at this.

CREATE TABLE #Details(ID INT IDENTITY(1,1),_Date DATE ,Payment INT,
LoanAmount INT)
DECLARE #Date DATE,#Payment INT,#LoanAmount INT,#PreLoanAmount INT
IF NOT EXISTS(SELECT 1 FROM #Details)
BEGIN
INSERT INTO #Details(_Date ,Payment ,LoanAmount )
SELECT #Date,#Payment,#LoanAmount
END
ELSE
BEGIN
SELECT TOP 1 #PreLoanAmount = LoanAmount FROM #Details ORDER BY ID DESC
INSERT INTO #Details(_Date ,Payment ,LoanAmount )
SELECT DATEADD(MONTH,1,#Date),#Payment,#PreLoanAmount - #Payment
END

Related

Get string value from one column of MySQL Table and update its other column value of same row

I have a Data Base Table whee i want to retrieve API-KEY column value and update the USED-VALUE column by 1 of the same row. I want to fetch the API-KEY value until the USED-VALUE reach to 20, if it reach to 20 then i will retrieve API-KEY value from next row and update the USED-VALUE column by one. I want this to be repeat for all the rows.
i am attaching my table here
Get first row where used_val is < 20 ordered by date
SELECT * FROM <table> WHERE used_val < 20 ORDER BY today_date DESC LIMIT 1;
Then get the ID and update used_val
UPDATE <table> SET used_val = CAST(used_val as INTEGER) + 1 WHERE id = <id_retrieved>;
Note: you should use proper data types for each column.
today_date should be datetime or timestamp
used_val should be integer

Copy - Paste rows using MySQL INSERT INTO

I have a table that contains many rows, ordered by the field 'seq'.
I have selected rows 6-9 and I want to copy and paste them on row 3 for example.
For that I'd like to create an SQL query that does the following:
INSERT INTO my_table ( seq, field1, field2.... )
SELECT seq, field1,field2..
FROM my_table
WHERE id IN ( 234, 233,232 )
(id field is the auto increment field that identifies my selected rows).
Now - I managed to duplicate the rows into the table.
What is missing is to correctly update the 'seq' field in the following manner :
In the pasted location (3) my rows should contain the values 3,4,5.
All the original rows in that location should be incremented by 3 so that the original row (seq=3) should now become (seq=6) and all rows move 3 rows down the table.
Can this be achieved with an SQL query ?
You can create a trigger which check for seq, if a sequence exists, it will update sequence numbers above it and will.
create table s_sequence
(seq number(3),
name varchar2(2000)
);
create or replace trigger s_seq_order
before insert on s_sequence
for each row
declare
seq_exists varchar2(20);
begin
begin
select 1 into seq_exists from s_sequence where seq = :new.seq;
exception
when NO_DATA_FOUND then
null;
end;
if seq_exists = '1' then
update s_sequence set seq = seq + 1 where seq >= :new.seq;
end if;
end;
inserting (seq, name) with (1, 'A') , (2, 'B') .. (5, 'E')
now insert (2, 'F')
But, I am not sure if this is an appropriate way to deal with order.
but why put any data in table in order ?
PS : This code tested in oracle.

FIFO type Recently Viewed Pages

I would like to create 20 rows of table data for to store recently viewed pages. The table row should not increase above 20 rows.
For an example, first 20 rows of page id with title will be stored in that table. when the 21st page viewed by the user, then the first post id and post title will be deleted (i.e., first viewed post) and insert (i.e., last viewed post) in the same table.
my table format:
-------------------------------|
ID | Post Title
-------------------------------|
1 | Post Title 1
2 | Post Title 2
3 | Post Title 3
...
20 | Post Title 20
-------------------------------|
if anyone please tell me how to do that with optimized qry.
You have two columns id and title. Let's consider that id will have any value even more than 20. At any time this table will contain maximums 20 rows (as per your need).
Understand following terms:
min(id) // will give minimum value in column id
max(id) // will give maximum value in column id
count(id) // counts total number of rows of your table
new_id // id of row which will be inserted next
Algorithm:
if(count(id)<20) // table have less than 20 rows so only insert
new_id = max(id)+1
insert the row with id as 'new_id' and page title
else // table have more than 20 rows so delete and then insert
delete row with id = min(id)
new_id = max(id)+1
insert the row with id as 'new_id' and page title
What above solution propose is if you have less than 20 rows keep on inserting because space is still there to insert. But, when you see that rows are more than or equal to 20 first delete the row with minimum id then insert the new row with maximum id of column by adding one.
You can do the following:
LOCK TABLES mytable;
INSERT INTO mytable (title) VALUES ('newtitle');
DELETE t FROM mytable t WHERE t.id IN (SELECT t2.id FROM (SELECT * FROM mytable) t2 ORDER BY t2.id DESC LIMIT 20,999999999); --Delete from 20 to "end"
UNLOCK TABLES;
First you need to add one column in table like created date
while inserting new record to this table, first check total number of rows in table
If rows count == 20 then write a query to delete one old record. use created_date to find it out...
if row count is < 20 then you can insert record directly...no pre-check required
Above step can be managed in only one query, If you are good at writing query
when user has viewed a page:
$query = mysqli_query("SELECT COUNT(ID) From your-table",$conn);
$result = mysqli_fetch_array($query);
$total = $row[0];
if($total<20){
//INSERT NEW ROW
$query = "INSERT INTO your-table() values(...,...)";
//etc ...
} else{
// DELETE THE FIRST ROW
$query = "DELETE FROM your-table ORDER BY ID ASC LIMIT 1";
// Then insert new row, etc...
}

Update another table when another one is updated

I'm not quite figuring out how to do what I'm after.So what I'm making is an online game.When a user buy's a new car I do an INSERT:
$c->query("INSERT INTO user_cars (carid, userid, acc, speed) VALUES ('$buyid','$id','$acc','$speed')");
Now I have another table that I need to insert info to right after the query above FROM the query above.What I need is the carid .The user can have more than 2 cars.What should I do now?
You have multiple options:
You can build a trigger to insert a new row in table2, when row is inserted in the cars table (Read more here http://dev.mysql.com/doc/refman/5.5/en/trigger-syntax.html)
There is this function mysql_insert_id() which returns the last inserted id ( Read more here http://php.net/manual/en/function.mysql-insert-id.php )
If you use PDO , there is a smillar command for it
etc.
This is a basic demonstration of the trigger you would want to create. For illustrative purposes I've also included the ddl and an example insert into your user_cars table to show that another table, which I've called "your_other_table" receives the insert (just the carid value) of an insert going into the user_cars table.
Fiddle:
http://sqlfiddle.com/#!9/f76a7/1/0
(notice how "your_other_tabe" has one row with the carid of the insert into "user_cars", despite having no direct inserts into itself)
delimiter //
create table user_cars
(
carid int,
userid int,
acc int,
speed int,
constraint id_pk primary key (carid, userid)
)//
create table your_other_table
(
carid int
)//
create trigger your_trigger_name before insert on user_cars
for each row begin
insert into your_other_table (carid)
values (new.carid);
end
//
insert into user_cars values
(1, 2, 3, 99)//
delimiter ;
select *
from your_other_table;
Output:
| CARID |
|-------|
| 1 |
This is the only portion of the above sql that creates the trigger:
delimiter //
create trigger your_trigger_name before insert on user_cars
for each row begin
insert into your_other_table (carid)
values (new.carid);
end
//
delimiter ;

Using php and Mysql to Order by highest number and confirmation

Well I have this mysql table with numbers in one column and a confirmation boolean of 0 or 1 and I have about 1,000 rows so it's not something I can do manually but anyways...
I want to sort the row by highest value and grab the names of the first 5 people and put those 5 people in another table on a column and then set them to confirmed and continue until there's no one left in the table that isn't confirmed...
ex:
Name:Rank:Confirm
Bob:5000:0
James:34:0
Josh:59:1
Alex:48:0
Romney:500:0
Rolf:24:0
Hat:51:0
so when you run the code it will do the following:
Squad:Name1:Name2:Name3:Name4:Name5
1:Bob:Romney:Hat:Alex:James
(as you can see Josh was excluded and Rolf was too low)
And since Rolf is alone and there are no one else left, he wont be put into a team and will be left unconfirmed...
I'm not really pro at mysql so I was stumped on this and at most was capable of organizing the whole thing by rank and that's it ._.
edit:
The terrible attempt I had at this:
<?php
$parse = mysql_query("SELECT MAX(rank) AS rank FROM users AND confirm='0'");
mysql_query("Insert into squad (nameone)values($parse)");
mysql_query("Update squad set confirm = '1' where name = $parse");
?>
Assuming confirm will have only either 1 or 0.
CREATE TABLE table2 (id INT PRIMARY KEY AUTO_INCREMENT, name varchar(255));
CREATE PROCEDURE rank()
BEGIN
DECLARE count INT DEFAULT 1;
WHILE count > 0 DO
UPDATE table1 SET Confirm=2 WHERE Confirm=0 ORDER BY Rank DESC LIMIT 5;
INSERT INTO table2 (SELECT GROUP_CONCAT(Name) FROM table1 WHERE Confirm=2);
UPDATE table1 SET Confirm=1 WHERE Confirm=2;
SELECT count(*) FROM table1 WHERE Confirm=0;
END WHILE;
END;
Call the procedure rank() when ever you want
CALL rank();

Categories