On Duplicate of entire rows of same values how to increase count? - php

I have a table using php mysql and using pdo for fetching records.
I want to know sql query so that if I insert row of all same values of same fields(duplicate row). It should insert new row by upgarding the count which is also one of the field
INSERT INTO table_name (column1, column2, column3, column4)
VALUES (value1, value2, value3,values4)
ON DUPLICATE KEY UPDATE count = count + 1;
this is hypothetical example
column2 is an id, which is foreign key constraints of another table2,
column3 is an id, which is foreign key constraints of another table3,
column4 is an id, which is foreign key constraints of another table4
total 4 tables I have. My table looks like this
Sno | column2_id | column3_id | count | column4_id
1 | column2_value | column3_value | 1 | column4_value
I have fetched all three tables data through id and show in table 1.
I have different values only 5 id in table 2 which have corresponding values.
if I insert new row of duplicate values it should insert by increasing count values.
By default I have taken count as 1.

I didn't understand very well your request.
But if I understand correctly you want to update a row if it is duplicate?
If so you can just use an ON DUPLICATE KEY UPDATE
For example :
INSERT INTO table_name (column1, column2, column3, number)
VALUES (value1, value2, value3, number)
ON DUPLICATE KEY UPDATE number = number + 1;

Related

Insert rows on one table based on the values of a field of another table in PHP-MySQL

I would like to ask for a solution on how to insert n rows based on the values of a field in another table.
Consider the following tables:
CREATE TABLE Input (
ID INT AUTO_INCREMENT PRIMARY KEY,
Name VARCHAR(128),
Ticket_Piece INT
);
CREATE TABLE Output (
Ticket_ID INT AUTO_INCREMENT PRIMARY KEY,
Transaction_ID INT,
Ticket_Number VARCHAR(23) UNIQUE,
FOREIGN KEY (Transaction_ID)
REFERENCES Input (ID)
ON UPDATE CASCADE
ON DELETE CASCADE
);
If a row from the Input table has n in the Ticket_Number column, then n rows should be inserted into the Output table, with Ticket_Number having values "ID-1" through "ID-n" (e.g. (4, "D", 5) in Input should result in rows with ticket numbers "4-1" through "4-5" being added to Output). How can rows for Output be generated in a range of numbers based on the Ticket_Piece column using PHP and MySQL?
For example, with the input:
INSERT INTO Input (ID, Name, Ticket_Piece)
VALUES
(1, 'A', 2),
(2, 'B', 1),
(3, 'C', 3)
;
the result should be:
Ticket_ID
Transaction_ID
Ticket_Number
1
1
1-1
2
1
1-2
3
2
2-1
4
3
3-1
5
3
3-2
6
3
3-3
For each row you fetch from the input table, use a for loop to insert multiple rows into the output table.
$res = $pdo->query("SELECT id, ticket_piece FROM Input_Table");
$insert_stmt = $pdo->prepare("INSERT INTO Output_Table (transaction_id, ticket_number) VALUES (:id, :ticket)");
while ($row = $res->fetch(PDO::FETCH_ASSOC)) {
$pieces = $row['ticket_piece'];
$id = $row['transaction_id'];
for ($i = 1; $i <= $pieces; $i++) {
$insert_stmt->execute([':id' => $id, ':ticket' => "$id-$i"]);
}
}
A solution in PHP or SQL will likely need to use a loop.
If this comes from the data model rather than business rules (and depending on other factors), a trigger might be a fairly simple option. The trigger body could have a WHILE or other loop to iterate over the ticket piece numbers, and CONCAT to combine the ID and piece number into a ticket number, inserting each in turn.
DELIMITER ;;
CREATE TRIGGER create_ticket_pieces
AFTER INSERT ON Input
FOR EACH ROW
BEGIN
DECLARE piece INT DEFAULT 1;
WHILE piece <= NEW.Ticket_Piece DO
INSERT INTO Output (Transaction_ID, Ticket_Number) Values (NEW.ID, Concat(NEW.ID, '-', piece));
SET piece := piece + 1;
END WHILE;
END;;
DELIMITER ;
An alternative some use is to pregenerate a table of numbers, then join with this table to generate rows:
INSERT INTO Output (Transaction_ID, Ticket_Number)
SELECT Input.ID, Concat(Input.ID, '-', Numbers.Number)
FROM Input
JOIN Numbers ON Numbers.Number <= Input.Ticket_Piece
WHERE ... -- select Input rows
It should be noted that by duplicating information (the transaction ID) in two different columns, the Output table isn't normalized. In particular, it violates 3rd normal form, due to a functional dependency of Transaction_ID on Ticket_Number. The way to resolve this is to leave the transaction ID out of the ticket number field (i.e. Output.Ticket_Number holds only the generated integer ≤ Input.Ticket_Piece). (See: "Third Normal Form: Composite PRIMARY KEY vs System-Generated Surrogate (IDENTITY)")

SQL Statement INSERT, on duplicate columns UPDATE

I have an SQL Table that contains a list of items that users can have linked to their profile. The SQL table looks something like this:
Item_Activity_ID Item_ID User_ID Status Date-Added
1 1 1 1 2015-06-08
2 2 2 1 2015-06-08
3 1 1 0 2015-06-09
The entry shows that someone with the user with id of 1 added item id 1 twice, and the only thing that was changed was the date and status. I want to make it so that when given an INSERT statement such as:
INSERT INTO items (Item_ID, User_ID, Status, Date_Added) VALUES ('$x', '$y', 1, CURDATE()) IF EXISTS SOME Item_ID = $x AND User_ID = $y UPDATE items SET Status = 1, Date_Added = CURDATE() WHERE Item_ID = $x AND User_ID = $y
Item_Activity_ID is an auto_incremented primary key index. How can I accomplish this in one query? Two users can have the same item, but where should never be repeat entries of the same user id and item id.
First, create a unique index for Item_ID, UserID combination,
Then, use the INSERT ... ON DUPLICATE KEY UPDATE statement:
INSERT INTO items (Item_ID, User_ID, Status, Date_Added)
VALUES ('$x', '$y', 1, CURDATE())
ON DUPLICATE KEY UPDATE Status = VALUES(Status), Date_Added = VALUES(Date_Added))
P.S. make sure to sanitize $x and $y to prevent SQL injections!
I would start by adding a unique key index:
ALTER TABLE items
ADD CONSTRAINT uc_UserItem UNIQUE (Item_ID,User_ID);
Then, you can just modify your insert query:
INSERT INTO items (Item_ID, User_ID, Status, Date_Added) VALUES ('$x', '$y', 1, CURDATE()) ON DUPLICATE KEY UPDATE Status=VALUES(1), Date_Added=VALUES(CURDATE());
Try to perform the update first supposing that the user and item already exist. Then check if this update affects any rows (using ##rowcount, in SQL Server).
If not then perform an insert.
Don't forget to put the above two statements in a transaction... ;)
Normal way would be to set a composite constraint at the db level. If you are using mysql and phpmyadmin you do this in the table structure view.
Check both fields (I guess 'user_id' and 'item_id') and click the 'unique' button.
After that is set you can just append
ON DUPLICATE KEY UPDATE status =1, date_added=CURDATE().
It will update the row that violated the constraint you created

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 ;

Insert into 2 table and set both foreign key auto increment

I have a database with two tables. When a user posts an article, it will be inserted into both tables, (2 queries in one file)
I use post_id as foreign key, both tables post_id auto increment. Will foreign keys be messed up? For example if users A and B query the database at the same time.
Table 1
post_id user...
1 A
2 B
Table 2
post_id content...
1 A
2 B
First off you can't have auto increment on both tables.
Usually, what you do is insert in table 1, get the ID of the just inserted row.
Then you use this ID, to insert in table 2 which references table 1.
See: mysqli::$insert_id at
http://www.php.net/manual/en/mysqli.insert-id.php
Example:
$query = "INSERT INTO table1(user,whatever) VALUES ('A','something')";
$mysqli->query($query);
printf ("New Record has id %d.\n", $mysqli->insert_id);
$query = "INSERT INTO table2(post_id,content) VALUES ($mysqli->insert_id,'This is content')";
$mysqli->query($query);
You could also do this using a stored procedure based on: stackoverflow.com/a/1723325/1688441
DELIMITER //
CREATE PROCEDURE new_post_with_content(
user_id CHAR(5), content_text CHAR(100)
BEGIN
START TRANSACTION;
INSERT INTO table1 (user)
VALUES(user_id);
INSERT INTO table2 (post_id, content)
VALUES(LAST_INSERT_ID(), content_text);
COMMIT;
END//
DELIMITER ;
And you call it like so:
CALL new_engineer_with_task('A','This is the content');
Why not use table1 as user table and second with posts?
users
user_id(autoinc) username
1 A
2 B
3 C
posts
post_id(autoinc) user_id posts_text
1 2 text
2 1 other text

Mysql not insert records

I have two tables: employee and employee_group. After insert to first table I will get last inserted id from this table. Next I need insert to table employee_group. SQL:
INSERT INTO employee_group (employee_id, group_id)
SELECT {$currentEmpId}, group_id
FROM employee_group
WHERE employee_id = {$anyId}
MySQL has been returned TRUE. But records have not inserted.
I noticed if try insert records for previous inserted employee then query will be successful. Example:
Insert to employee, will return $currentEmpId as last inserted id
INSERT INTO employee_group (employee_id, group_id) SELECT {$currentEmpId - 1}, group_id FROM employee_group WHERE employee_id = {$anyEmpId}
Or if I tried insert records for current employee and previous at the same time then first query will be unsuccessful but second query ok.
The database has not triggers, foreign keys or functions. Nothing, just data.
I'm in a deadlock.
UPD: If I take records to php variable then foreach it and insert each record as one item like INSERT INTO employee_group (employee_id, group_id) VALUES (xxx, yyy) I will get this problem too.
INSERT INTO employee_group (employee_id, group_id)
VALUES({$toEmpId},{SELECT group_id FROM employee_group WHERE employee_id = {$fromEmpId}})
Check it out ..
Try this
INSERT INTO employee_group (employee_id, group_id)
VALUES({$toEmpId},{SELECT {$toEmpId}, group_id FROM employee_group WHERE employee_id = {$fromEmpId}})

Categories