Use two columns auto increment ( laravel 4.1) - php

I have these tables
Hotels:
id = auto increment
name_hotel = text
....
Rooms:
id = auto increment
id_room = auto increment (just in same hotel)
hotel_id = integer
...
In room table I have three columns (id = auto increment , id_room = I want to make this column auto increment but just in 1 hotel , every hotel add room the id_room will be 1 , 2 ,3 ,4 )
Example:
id id_room hotel_id
1 1 4
2 2 4
3 3 4
4 1 (start again) 5(new hotel)
5 4 4
6 2 5
It possible to make it in laravel model Eloquent

Well, if you know the hotel ID when you insert your data, then you can set the id_room to be one more than the highest ID room of that hotel.
First, remove the auto increment from id_room. Auto increment is intended to be used with primary keys or on rows whose IDs should always increment. It is never a good idea to try and reset the counter and as far as I know Laravel does not give you the option. But by removing the auto_increment, we can create one ourselves that does what you need.
To do so, we can use Eloquent to select the max(id_room) where hotel_id=?:
$id = 4; // or whatever ID you are inserting
$current_id = DB::table('rooms')->where('hotel_id', $id)->max('id_room');
Then, just add one to the current_id when you insert your data
$row = DB::table('rooms')->insert(
['id_room' => $current_id + 1, 'hotel_id' => $id];
);

Related

How to update my table using Arithmetic Operator by using update_batch in Codeigniter?

I am trying to update my table using update batch.
so I have this table columns
ID | Description | Total
1 Test 1 10
2 Test 2 15
3 Test 3 20
My main goal is to update the Total column using update batch, so i will not need to update them one by one.
so I don't have to do this one by one on my loop, instead i can just do update_batch
UPDATE table
SET Total = Total + 10
WHERE ID = 1;
UPDATE table
SET Total = Total + 25
WHERE ID = 2;
UPDATE table
SET Total = Total + 30
WHERE ID = 3;
How can I do this using update_batch?
Here is the code the I currently have
Controller:
foreach($total_debit as $list){
$data[] = array(
"ID" => $list->ID,
"Total" => Total + $list->value_to_be_added, //10
);
}
$this->Employee_model->update_total_value($data);
Model:
public function update_total_value($data){
$this->db->update_batch('employees', $data,"ID");
}
Can anyone help me if this is possible to do?

how to increment 1 every row after get row id in sql

i have a one question for increment +1 in every row
i have a sql table in that table have order_status column when new record created order_status will be store +1 then older record in that case if i have order status like 0 1 2 3
but when user send me order status 2 for 5th record so in this case record no 5 will be store as a record status 2 but i need to change status aftr 2 like
2 will be 3, 3 will be 4, 4 will be 5
if its posible so please me sql query
Use an UPDATE query.
UPDATE yourTable
SET order_status = order_status + 1
WHERE order_status >= 2

php pdo copy column between tables

I got the two tables(Table1 and Table2):
Table1:
id hits url
1 11 a
2 5 b
3 6 c
4 99 d
5 14 e
Table2:
id url 2014.04.13 2014.04.14
1 a 0 5
2 b 0 1
3 c 0 3
4 d 0 60
5 e 0 10
hi all,
Table1 one contains the actual hits(which are always up-to-date) and Table2 to statistics(which are done every day at midnight). The columns id(unique number) and url are in both tables the same. So they got the same amount of rows.
So i create every day a new column(with the date of today) and copy the column hits from the table 'Table1' into the new created column into the table 'Table2'
First i alter Table2:
$st = $pdo->prepare("ALTER TABLE Table2 ADD `$today_date` INT(4) NOT NULL");
$st->execute();
Then i cache all entries i need from Table1:
$c = 0;
$id = array();
$hits = array();
$sql = "SELECT id, hits FROM Table1 ORDER BY id ASC";
$stmt = $pdo->query($sql);
while($row = $stmt->fetch(PDO::FETCH_ASSOC))
{
$id[$c] = $row['id'];
$hits[$c] = $row['hits'];
$c++;
}
At last i update Table2:
for ($d = 0 ; $d < $c ; $d++)
{
$id_insert = $id[$d];
$sql = "UPDATE DOWNLOADS_TEST SET `$datum_det_dwnloads`=? WHERE id=?";
$q = $pdo->prepare($sql);
$q->execute(array($hits[$d], $id[$d]));
if($q->rowCount() == 1 or $hits[$d] == 0) // success
$hits[$d] = 0;
else // error inserting (e.g. index not found)
$d_error = 1; // error :( //
}
So what i need is to copy(insert) a column from one table to another.
The two tables are having ~2000 elements and the copying as described above takes around 40 sec. The bottleneck is the last part (inserting into the Table2) as i found out.
One thing i found is to do multiple updates in one query. Is there anything i can do besides that?
I hope you realise that at some point your table will have irrational number of columns and will be highly inefficent. I strongly advise you to use other solution, for example another table that holds data for each row for each day.
Let's say you have a table with 2000 rows and two columns: ID and URL. Now you want to know the count of hits for each URL so you add column HITS. But then you realise you will need to know the count of hits for each URL for every date, so your best bet is to split the tables. At this moment you have one table:
Table A (A_ID, URL, HITS)
Now remove HITS from Table A and create Table B with ID and HITS attributes). Now you have:
Table A (A_ID, URL)
Table B (B_ID, HITS)
Next move is to connect those two tables:
Table A (A_ID, URL)
Table B (B_ID, A_ID, HITS)
Where A_ID is foreign key to attribute "A_ID" of Table A. In the end it's the same as first step. But now it's easy to add date attribute to Table B:
Table A (A_ID, URL)
Table B (B_ID, A_ID, HITS, DATE)
And you have your solution for database structure. You will have a lot of entries in table B, but it's still better than a lot of columns. Example of how it would look like:
Table A | A_ID | URL
0 index
1 contact
Table B | B_ID | A_ID | HITS | DATE
0 0 23 12.04.2013
1 1 12 12.04.2013
2 0 219 13.04.2013
3 1 99 13.04.2013
You can also make unique index of A_ID and DATE in Table B, but I prefer to work on IDs even on linking tables.

SQL update multiple rows with different values, without specifying unique key

I need help building a SQL query which searches for an user_id (let's say user_id = 5), but this user_id has multiple row entries, but I need to update each row differently though.
I have an array with data which I want to assign to that user_id. Here is a table example:
id user_id amount txn_id
1 5 10 foo_unique
2 5 5 bar_unique
3 7 15 xyz_unique
4 5 10 123_unique
My array would look something like this:
Array (
[0] => 14
[1] => 6
[2] => 9
)
As you see I have three array values and three rows for user_id 5, now I want to add each value of that array, to the corresponding user_id (5). Note that I have an UNIQUE column named txn_id
After updating the table, it would look like this:
id user_id amount txn_id
1 5 14 foo_unique
2 5 5 bar_unique
3 7 6 xyz_unique
4 5 9 123_unique
Any ideas how I could achieve this?
Thanks.
P.S: I cannot use SQL CASE on this issue.
If you want to update one row with a value, you have to be able to have a unique condition for that row.
Without adding some extra field, or condition to uniquely identify a row, you are out of luck.
You can use the following query:
UPDATE MyTable
SET
amount =
CASE id
WHEN 1 THEN 14
WHEN 2 THEN 6
WHEN 3 THEN 9
ELSE amount -- just in case user_id 5 has records not covered above.
END
WHERE
user_id = 5
The problem is, there is nothing on your array that says which array entry belongs to which database row. If you want to rely just on the orders (of the array indices, and the database ids,), you have to SELECT all rows for the user first, then loop and update a row at a time. Something like this on PHP (and PDO):
$values = array(14, 6, 9);
$dbh = new PDO('mysql:host=localhost;dbname=yourdbname', 'username', 'password');
$selectQuery = 'SELECT id FROM yourtable WHERE user_id = 5 ORDER BY id';
foreach($dbh->query($selectQuery) as $row) {
$id = $row['id'];
$sth = $dbh->prepare("UPDATE yourtable SET amount = :val WHERE id = :id");
$sth->execute(array(
'val' => array_unshift($values),
'id' => $id
));
}
(Code above assumes the number of values on your arrays matches the number of database rows for user_id = 5).
Looking at the problem you only need to have SQL statements.
First is to create two tables:
CREATE TABLE users
user_id int(11) PRIMARY KEY NOT NULL,
username varchar(25),
) Engine = InnoDB;
CREATE table userbalances (
balance_id int(11) PRIMARY KEY NOT NULL,
user_id int(11),
amount decimal(10,2),
CONSTRAINT userid_fk FOREIGN KEY userid_fk(user_id) REFERENCES users(userid)
) Engine = InnoDB;
Then, after you have INSERT(ed) all of the users and userbalances inside the table, all you need to do is create an UPDATE statement to update the amount:
UPDATE userbalances SET amount=? WHERE user_id=? AND balanceid=?
The update should be in a loop. And you should use mysql_query() function to update it with the assigned arrays that you have.
Note:
Both userid and balanceid should be in the WHERE clause of your UPDATE statement because you have multiple transactions inside the userbalances table. Otherwise, it's going to change all of the balances of all the transactions of that user.
Problem update:
If you don't use any SQL Cases on this problem, then your problem is just PHP. You need to find out what is the function for UPDATE(ing) - to update the amounts. As long as your tables are all prepopulated. There might be a function on the program you use to update it.

MYSQL : How to set to same position if row value is the same?

position | Average | gpmp
1 70.60 2.0
2 60.20 2.3
3 59.80 4.8
4 59.80 4.8
5 45.70 5.6
Hie All,
As above table, I need to arrange the position according to the lowest gpmp and the highest average. But when the both average and gmp are the same, I will need to have the position to be the same.
For example, position 3 and 4 have the same average and gpmp. How do I generate the mysql query or using php function so that after they detect the same average and gpmp and change the position 4 to 3.
Which mean after the function is generated it will become like the table below.
position | Average | gpmp
1 70.60 2.0
2 60.20 2.3
3 59.80 4.8
3 59.80 4.8
5 45.70 5.6
Here's a simple way to update the table as you described in your post - taking the sequential positions and updating them accordingly. It doesn't calculate the positions or anything, just uses the data already there:
UPDATE `table` t SET position = (
SELECT MIN(position) FROM (SELECT * FROM `table`) t2 WHERE t.Average = t2.Average AND t.gpmp = t2.gpmp
)
I'd give something like the following a try, through it does assume a primary key is on this table. Without a primary key you're going to have issues updating specific rows easily / you'll have a lot of duplicates.
So for this example I'll assume the table is as follows
someTable (
pkID (Primary Key),
position,
Average,
gpm
)
So the following INSERT would do the job I expect
INSERT INTO someTable (
pkID,
position
)
SELECT
someTable.pkID,
calcTable.position
FROM someTable
INNER JOIN (
SELECT
MIN(c.position) AS position,
c.Average,
c.gpm
FROM (
// Calculate the position for each Average/gpm combination
SELECT
#p = #p + 1 AS position,
someTable.Average,
someTable.gpm
FROM (
SELECT #p:=0
) v,someTable
ORDER BY
someTable.Average DESC,
someTable.gpmp ASC
) c
// Now regroup to get 1 position for each combination (the lowest position)
GROUP BY c.Average,c.gpm
) AS calcTable
// And then join this calculated table back onto the original
ON (calcTable.Average,calcTable.gpm) = (someTable.Average,someTable.gpm)
// And rely on the PK IDs clashing to allow update
ON DUPLICATE KEY UPDATE position = VALUES(position)
(pseudo code)
select * from table
get output into php var
foreach (php row of data)
is row equal to previous row?
yes - don't increment row counter, increment duplicate counter
no - increment row counter with # of duplicates and reset duplicate counter
save current row as 'previous row'
next
you can try something like this in php:
$d= mysql_query('select distinct gpmp from tablename order by gpmp');
pos= 1;
while($r= mysql_fetch_array($d)){
mysql_query('update tablename set position='.$pos.' where gpmp='.$r['gpmp']);
$pos++;
}
You only need to "expand" the idea to take averange in account too.

Categories