dedupe mysql table but ignore empty values - php

I have a php script that uploads csv files into a mysql database.
The database has several columns. Among these columns is an 'email' field. I wrote some mysql that would remove rows that contained duplicate values in the email column. Below is the mysql:
$sql = "CREATE TABLE new_table as SELECT * FROM auto WHERE 1 GROUP BY email";
mysql_query($sql, $conn);
$query = mysql_query("SELECT COUNT(*) FROM new_table");
list($number) = mysql_fetch_row($query);
$query = mysql_query("SELECT COUNT(*) FROM auto");
list($number2) = mysql_fetch_row($query);
$result = $number2 - $number;
mysql_query("DROP TABLE auto");
mysql_query("RENAME TABLE new_table TO auto");
The code works, it removes duplicate values.
Problem:
It removes rows that contain no values. So it assumes that two or more emails values that are empty are duplicates and removes they're rows.
Question:
How do I tell mysql to ignore empty values.
Thanks for the help.
Edit
The where is my database table. One table.
The when is when I execute the code. I plan on putting in a php file to be executed on demand.
The result I expect is a mysql table without duplicate emails.

Something like this would work for a one-time alteration, by allowing NULL in email, and adding a UNIQUE constraint:
-- set empties to NULL
UPDATE tablename SET email = NULL WHERE LENGTH(email)=0;
-- drop all rows violating the UNIQUE constraint on email:
ALTER IGNORE TABLE tablename ADD UNIQUE (email);

Related

Prevent Select sql from select the same data from DB PHP

I Have some question about the Seq in PHP.
I create 1 tabel to maintain the sequence table,
ex. table is sequence and the field is seq(start from 1)
The sequence should be unique value.
The problem is.
there is 2 process which is run parallel that will use it.
and I got the error message that say duplicate value.
The question.
How to lock the table from another select query?
this is my code
//select seq
$sqlSeq = "select seq from sequence for update";
$resultSeq = pg_query($sqlSeq);
$rowSeq = pg_fetch_assoc($resultSeq);
$seqCif = $rowSeq['seq'];
//INSERT
$sqlInsert1 ="insert into TEST (customer_id) values( '".$seqCif."')";
//UPDATE
$sqlInsert1 .= "update sequence set seq=seq+1;" ;
Can you help me for this case?
Many Thanks befor..
One simple way to make the operation atomic and to guarantee an incremental id without gaps is to turn the statement to an insert ... select ... query:
insert into test(customer_id)
select coalesce(max(customer_id), 0) + 1 from test

INSERT MULTIPLE ROWS in Gerund Table using Insert Into Select

I used INSERT INTO SELECT to copy values (multiple rows) from one table to another. Now, my problem is how do I insert rows with its corresponding IDs from different tables (since it's normalized) into a gerund table because it only outputs one row in my gerund table. What should I do to insert multiple rows and their corresponding IDs in the gerund table.
My code for the gerund table goes like this.
$insert = "INSERT INTO table1 SELECT * FROM sourcetable"; // where id1 is pk of table1.
$result =mysqli_query($conn,$insert)
$id1=mysqli_insert_id($conn);
Now table 1 has inserted multiple rows same as the other 2 tables.
Assuming id.. are the foreign keys
INSERT INTO gerundtable (pk, id1,id2,id3) VALUES ($id1,$id2,$id3);
My problem is it doesn't yield multiple rows.
According to MySql documentation:
For a multiple-row insert, LAST_INSERT_ID() and mysql_insert_id() actually return the AUTO_INCREMENT key from the first of the inserted rows. This enables multiple-row inserts to be reproduced correctly on other servers in a replication setup.
So, grab the number of records being copied, and the LAST_INSERT_ID() and you should be able to map exact IDs with each copied row.
In the lines of:
$mysqli->query("Insert Into dest_table Select * from source_table");
$n = $mysqli->affected_rows; // number of copied rows
$id1 = $mysqli->insert_id; // new ID of the first copied row
$id2 = $mysqli->insert_id + 1; // new ID of the second copied row
$id3 = $mysqli->insert_id + 2; // new ID of the third copied row
...
$mysqli->query("INSERT INTO gerundtable (pk, id1,id2,id3) VALUES ($id1,$id2,$id3)");
Thank you for trying to understand and also answering my question. I resolved my own code. I used while loop to get the ids of every row and didn't use INSERT INTO SELECT.
Here is the run down. SInce I'm just using my phone bare with my way posting.
$sqlselect = SELECT * FROM table1;
While($row=mysqli_fetch_array(table1){
$insertquery...
$id1=mysqli_insert_id($conn)
$insertgerundtable = INSERT INTO gerundtable VALUES ( $id1, $id2);
}

INSERT where doesn't exist in php script, comparing 2 tables

I currently have a script that runs every 5 minutes and selects the data from a table on server 1 and an identical table on server2. This is a workaround for replication, essentially, since we don't have that option currently.
The script is successful but I've realized that it misses records sometimes, for whatever reason. The current script selects all records from the destination table, stores the max primary key, selects all data from the source table and then inserts anything with a greater Primary key into the dest. table.
I'd like to modify the script slightly and instead of using max id, just say "if a row has an primary key that doesn't exist in the destination table, insert that row there."
Again these are cloned tables so the structure is the same and they both use AI Primary Keys.
Here's the current working script:
$latest_result = $conn2->query("SELECT MAX(`SESSIONID`) FROM
`ambition`.`session`");
$latest_row = $latest_result->fetch_row();
$latest_session_id = $latest_row[0];
//Select All rows from the source phone database
$source_data = mysqli_query($conn, "SELECT * FROM
`cdrdb`.`session` WHERE `SESSIONID` > $latest_session_id");
// Loop on the results
while($source = $source_data->fetch_assoc()) {
// Check if row exists in destination phone database
$row_exists = $conn2->query("SELECT SESSIONID FROM
ambition.session WHERE SESSIONID = '".$source['SESSIONID']."' ") or
die(mysqli_error($conn2));
//if query returns false, rows don't exist with that new ID.
if ($row_exists->num_rows == 0){
//Insert new rows into ambition.session
$stmt = $conn2->prepare("INSERT INTO ambition.session (SESSIONID,
SESSIONTYPE,CALLINGPARTYNO,FINALLYCALLEDPARTYNO,
DIALPLANNAME,TERMINATIONREASONCODE //etc. There are a lot of columns so I
ommitted the others
Is there a way I can slightly modify this to just insert what doesn't exist rather than relying on the MAX ID?
Or is there something here that would be a culprit as to why it's missing records?
You could use INSERT INTO SELECT and check if value is already in target:
INSERT INTO trg_table (cols)
SELECT cols
FROM src_table s
WHERE NOT EXISTS (SELECT 1 FROM trg_table t WHERE t.id = s.id);

mysql insert record not immediately available, select count(*) doesn't see it right away

In my php code, I have a Mysql query:
SELECT COUNT(*)
to see if the record already exists, then if it doesn't exist I do an:
INSERT INTO <etc>
But if someone hits reload with a second or so, the SELECT COUNT(*) doesn't see the inserted record.
$ssql="SELECT COUNT(*) as counts FROM `points` WHERE `username` LIKE '".$lusername."' AND description LIKE '".$desc."' AND `info` LIKE '".$key."' AND `date` LIKE '".$today."'";
$result = mysql_query($ssql);
$row=mysql_fetch_array($result);
if ($row['counts']==0) // no points for this design before
{
$isql="INSERT INTO `points` (`datetime`,`username`,`ip`,`description`,`points`,`info`, `date`,`uri`) ";
$isql=$isql."VALUES ('".date("Y-m-d H:i:s")."','".$lusername."',";
$isql=$isql."'".$_SERVER['REMOTE_ADDR']."','".$desc."','".$points."',";
$isql=$isql."'".$key."','".$today."','".$_SERVER['REQUEST_URI']."')";
$iresult = mysql_query($isql);
return(true);
}
else
return(false);
I was using MyISAM database type
Instead of running two seperate queries just use REPLACE INTO.
From the documentation:
REPLACE works exactly like INSERT, except that if an old row in the table has the same value as a new row for a PRIMARY KEY or a UNIQUE index, the old row is deleted before the new row is inserted.
For example if your key field is id then:
REPLACE INTO my_table SET id = 4 AND other_field = 'foobar'
will insert if there is no record with id 4, or if there is then it will replace the other_field value with foobar.

php/mysql creating duplicate records with multiple tables

I'm building a database for making hotel reservations. One table called "reservations" holds the general details of the reservation, while another called "rooms" holds details about specific rooms (each reservation has many rooms, each room belongs to only one reservation).
I would like to be able to easily generate duplicate reservations records (except for the primary key, of course). My problem is in generating the rooms data as an array which is then inserted into the rooms table while being associated to its reservation.
I've come as far as the following trivial code (stripped down to the bare essentials for discussion purposes).
if (isset($_POST['action']) and $_POST['action'] == 'Duplicate')
{
include $_SERVER['DOCUMENT_ROOT'] . '/includes/connect.inc.php';
$id = mysqli_real_escape_string($link, $_POST['id']);
// retrieve reservation
$sql = "SELECT type_of_reservation FROM reservations WHERE id='$id'";
$result = mysqli_query($link, $sql);
$row = mysqli_fetch_array($result);
$type_of_reservation = $row['type_of_reservation'];
// create new reservation record
$sql = "INSERT INTO reservations SET type_of_reservation ='$type_of_reservation'";
$id = mysqli_insert_id($link);
// retrieve rooms
$sql = "SELECT reservation_id, in_date FROM rooms WHERE reservation_id='$id'";
$result = mysqli_query($link, $sql);
while ($row = mysqli_fetch_array($result))
{
$rooms[] = array('reservation_id' => $row['reservation_id'], 'in_date' => $row['in_date']);
}
The big question is, now what? Everything I've tried either generates an error or no new entries, and I can't seem to find any discussion that addresses this specific need. Thanks for your help.
PeterC, there is no code listed that shows you inserting the ROOM record information. In the //retrieve room section of your code, you are pulling the data and putting it into an array. If you really want to create a duplicate records, I would use in insert inside the database, then you don't have to pull the records out just to put them back in.
The bit of code you want will be something like this. It will be in place of the //retrieve rooms code you have listed: (psuedo code) [note: $id represents the newly selected id from your sql insert for the duplicated reservation]
INSERT INTO rooms(res_id, other, data)
SELECT $id, other, data FROM rooms WHERE id = $_POST['id'];
This will allow you to duplicate the room data, adding the new reservation_id right inside the database. No need to pull out the records, create inserts, and then put them back in. You can read more about INSERT INTO ... SELECT statements here: http://dev.mysql.com/doc/refman/5.0/en/ansi-diff-select-into-table.html
// create new reservation record
$sql = "INSERT INTO reservations SET type_of_reservation ='$type_of_reservation'";
//ADD HERE CODE BELOW
$id = mysqli_insert_id($link);
with mysql_insert_id you get the inseted id, but you should insert it into db.. so add
mysqli_query($link, $sql);
before retrieving data
If you simply need to duplicate records, you can do it this way:
INSERT INTO
reservations
(
SELECT
null, # assume first column is auto incrementing primary key, so leave null
`all`,
`other`,
`column`,
`names`
FROM
reservations
WHERE
reservation_id = $oldReservationId # id of reservation to duplicate
)
Then for the rooms use the last inserted id (for instance retrieved with mysql_insert_id), like this:
INSERT INTO
rooms
(
SELECT
null, # assume first column is auto incrementing primary key, so leave null
$newReservationId, # this is the new reservation id
`all`,
`other`,
`column`,
`names`
FROM
rooms
WHERE
reservation_id = $oldReservationId # id of reservation to duplicate
)

Categories