I'm doing a program where I’m comparing in a database (Mysql-Workbench) 2 columns (difficulty, difficulty_student) of 2 different tables (EXERCISES, ANSWERS) in a column difficulty_choice of the table ANSWERS.
This is what I mean:
I’m comparing both tables using a VARCHAR (YES or NO). If the user has changed the difficulty of the exercise, the cell will be 'YES', if it has not been changed, the cell will be 'NO'.
These are my tables:
CREATE TABLE exercises (
exercise_id INT,
difficulty VARCHAR(30),
PRIMARY KEY(exercise_id)
);
CREATE TABLE answers(
exercise_id_fk INT,
student_id INT,
difficulty_change VARCHAR(3),
difficulty_student VARCHAR(30),
FOREIGN KEY(exercise_id_fk) REFERENCES exercises(exercise_id)
);
My problem is that the rows of the ANSWERS table don’t exist until the user presses the SUBMIT button in the program. So I have only managed to compare the columns that are in the table using the commands below in Mysql-Workbench.
What I need is to compare the columns in difficulty_change when the user presses SUBMIT. Can you help me do it? I can not get it.
I have managed to compare the columns using the following codes but I want them to be called from the program so that I do not have to go to Mysql-Workbench every time to execute them.
SELECT e.difficulty, a.difficulty_student,
case when e.difficulty = a.difficulty_student then 'NO' else 'YES'
END as difficulty_change
FROM exercises e
INNER JOIN answers a on e.exercise_id=a.exercise_id_fk;
UPDATE answers a
INNER JOIN exercises e on e.exercise_id=a.exercise_id_fk
set a.difficulty_change = case
when e.difficulty = a.difficulty_student then 'NO' else 'YES' END
where e.exercise_id=a.exercise_id_fk;
This is my PHP, it might help:
<?php
if (isset($_POST['submit'])) {
$user_id = $_SESSION['user_id'];
$user_check_query = "SELECT * FROM users WHERE id='$user_id'";
if(isset($_POST['choice'], $_POST['choose'])){
$choice_answer=$_POST['choice'];
$difficulty=$_POST['choose'];
// */$user_id = $_SESSION['user_id'];*/
$query = "INSERT INTO answers (exercise_id_fk, student_id, difficulty_student, choice_answer) VALUES ('$id','$user_id', '$difficulty', '$choice_answer')";
$sql=mysqli_query($conn,$query);
}
}
?>
Try:
$query = "INSERT INTO answers (exercise_id_fk, student_id, difficulty_change, difficulty_student, choice_answer) VALUES ('$id','$user_id', (SELECT IF(difficulty='$difficulty','NO','YES') FROM exercises WHERE exercise_id=$id), '$difficulty', '$choice_answer')";
Use your submit step to only update the db. Add code to query the db again to retrieve the data. Add a line to call your display page again (your display page calls itself) to display your updated table.
Related
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);
Im creating a website for booking activities. I have 3 centres. The customer is cant book the same activity twice neither in a different centre. Im using a table in mysql which i store the infos provided by the costumers. Is there any way to filter or to check in my php code if a customer has already booked the same activity more than one time and echo an error msg?
my table(and the info im asking) contains these columns:
ID(Primary)
FirstName
LastName
Email
ContactNumber
ClassName
Week
Intensity
CentreName
$values = $_POST;
foreach ($values as &$value) {
$value = mysql_real_escape_string($value);
}
$sql1="INSERT INTO loan (loan_id)
VALUES ('$values[loan_id]')";
$result = mysql_query($sql1);
if (!$result) {
die('Invalid query: ' . mysql_error());
}
When you create the table add the unique attribute to the fields you want to prevent, something like this
CREATE TABLE Persons
(
P_Id INT NOT NULL AUTO_INCREMENT,
LastName VARCHAR(255) NOT NULL,
FirstName VARCHAR(255),
Address VARCHAR(255),
City VARCHAR(255),
UNIQUE (P_Id)
)
If you already have created the table just edit it like this
ALTER TABLE Persons
ADD UNIQUE (P_Id)
Hope this helps you; If you do not have a unique id i believe this will suit you best on what you need; Note that this is not the full code; You need to add some to other information to fit in your question;
// Checks if the value already exist on the database
$query = SELECT EXISTS(SELECT column_name FROM table_name WHERE
condition LIMIT 1)
// If condition is not met it will proceed with save
if (mysql_num_rows(!$query) > 0) {
echo "Activity Booked";
} else { // If condition is met it will echo an error message
echo "Unable to booked activity"; }
You need to create a unique (composite) index on the column(s) that you wish to be unique. You can disregard your PK when making your unique index. In your case your sql would look something like:
Alter table yourtablename
add unique index idx_unq(`LastName`, `FirstName`, `Email`, `ContactNumber` `ClassName`, `Week`, `Intensity`, `CentreName`);
Then do an INSERT IGNORE INTO instead of an INSERT INTO.
This post may also help you.
"INSERT INTO .. ON DUPLICATE KEY UPDATE" Only inserts new entries rather than replace?
In order to see if record already exist in table you must first "test" to see if that exact record exist in your table. This is to be done before the 'Insert IGNORE Into' in your logic. Using the variables your code would look something like this:
$testcount = "Select count(`LastName`, `FirstName`, `Email`, `ContactNumber` `ClassName`, `Week`, `Intensity`, `CentreName`)
from yourtablename
where
(LastName = '$LastName' AND FirstName= '$FirstName' AND Email= '$EMAIL' AND ContactNumber= '$ContactNumber' AND ClassName= '$ClassName' AND Week= '$Week' Intensity = '$Intensity' AND CentreName = '$CentreName' )";
This query will give you back (assuming there are no duplicates already in the table) a 0 or a 1 and store it in your $testcount variable. This can then be used to either determine based on the value to insert the record into the table or print a message to end user informing them that it already exist.
I am not sure how you want to structure the php code but the psuedocode would look something like:
If $testcount = 1 then do your insert.
else if $testcount = 0 then echo your message.
I recently asked a question about writing to multiple tables: PHP/MySQL insert into multiple data tables on submit
I have now tried out this code and there are no errors produced in the actual code but the results I am getting are strange. When a user clicks register this 'insert.php' page is called and the code can be found below.
<?php
$username = $_POST["username"];
$password = $_POST["password"];
$institution = $_POST["institution"];
$conn = pg_connect("database connection information"); //in reality this has been filled
$result = pg_query($conn, "INSERT INTO institutions (i_id, name) VALUES (null, '$institution') RETURNING i_id");
$insert_row = pg_fetch_row($result);
$insti_id = $insert_row[0];
// INSTITUTION SAVED AND HAS ITS OWN ID BUT NO MEMBER OF STAFF ID
$resultTwo = pg_query($conn, "INSERT INTO staff VALUES (NULL, '$username', '$password', '$insti_id'");
$insert_rowTwo = pg_fetch_row($resultTwo);
$user_id = $insert_rowTwo[0];
// USER SAVED WITH OWN ID AND COMPANY ID
// ASSIGN AN INSTITUTION TO A STAFF MEMBER IF THE STAFF'S $company_id MATCHES THAT OF THE
// INSTITUION IN QUESTION
$update = pg_query($conn, "UPDATE institutions SET u_id = '$user_id' WHERE i_id = '$insti_id'");
pg_close($conn);
?>
What the result of this is just the browser waiting for a server response but there it just constantly waits. Almost like an infinite loop I'm assuming. There are no current errors produced so I think it may be down to a logic error. Any ideas?
The errors:
RETURNING clause is missing in the second INSERT statement.
Provide an explicit list of columns for your second INSERT statement, too.
Don't supply NULL in the INSERT statements if you want the column default (serial columns?) to kick in. Use the keyword DEFAULT or just don't mention the column at all.
The better solution:
Use data-moidifying CTE, available since PostgreSQL 9.1 to do it all in one statement and save a overhead and round trips to the server. (MySQL knows nothing of the sort, not even plain CTEs).
Also, skip the UPDATE by re-modelling the logic. Retrieve one id with nextval(), and make do with just two INSERT statements.
Assuming this data model (you should have supplied that in your question):
CREATE TABLE institutions(i_id serial, name text, u_id int);
CREATE TABLE staff(user_id serial, username text, password text, i_id int);
This one query does it all:
WITH x AS (
INSERT INTO staff(username, password, i_id) -- provide column list
VALUES ('$username', '$password', nextval('institutions_i_id_seq'))
RETURNING user_id, i_id
)
INSERT INTO institutions (i_id, u_id, name)
SELECT x.i_id, x.user_id, '$institution'
FROM x
RETURNING u_id, i_id; -- if you need the values back, else you are done
Data model
You might think about changing your data model to a classical n:m relationship.
Would include these tables and primary keys:
staff (u_id serial PRIMARY KEY, ...)
institution (i_id serial PRIMARY KEY, ...)
institution_staff (i_id, u_id, ..., PRIMARY KEY(i_id, u_id)) -- implements n:m
You can always define institution_staff.i_id UNIQUE, if a user can only belong to one institution.
I am having a problem locating comments for a given user with the following table structure:
usertable (id, userid, name)
comments (id, commentname, date)
Note: usertable.id is not the same as comments.id, and they are both autoincrement
How should I go about updating these tables to fix this problem?
Update
Is this code good for all users get their own votes when someone voted as thilo savage told me ?
$sth = thumbsup::db()->prepare(
'INSERT INTO'
.thumbsup::config('database_table_prefix')
.'votes_users(vid, userid) VALUES (?,?)');
$sth->execute(array($this->vid, $userid));
You've got two options:
Add a 'uid' column to the comments table which references the usertable's 'id' column. That way, you have a way to keep track of which comments belong to which users.
Create a table 'user_comment' with the columns 'uid' and 'cid'. This option leaves the two existing tables as they are, and the 'user_comment' table is responsible for keeping track of which comments belong to which users.
EDIT: Rewritten to use many-to-many relationship because current tables can't be altered.
Create a new table called comments_users with these fields:
cuid (primary key and auto increment) | cid | uid
Then get all of a user's comments with this code:
$user_id = '1234';
// get all the user's comment ids from comments_users table
$find = mysql_query("SELECT `cid` FROM `comments_users` WHERE `uid` = '".$user_id."'");
// generate a query that grabs all those comments
$load = "SELECT * FROM `comments` WHERE ";
while ($row = mysql_fetch_array($find) {
$load .= "`id` = '".$row['cid']."' OR ";
}
// shop off the last OR
$load = substr($load,0,-4);
// put all the user's comments into comments array
$q = mysql_query($load);
while ($comment = mysql_fetch_array($q)) {
$comments[] = $comment
}
print_r($comments);
As far as inserting goes, you'll insert comments into the comments table like you normally would, but then you'd ALSO insert a row into comments_users table filling in the appropriate cid and uid for that comment
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
)