Insert Into on Duplicate Update creates me an unwanted row - php

I have a SQL query as follows-
"INSERT INTO users(id, rank) SELECT v.user, v.vote FROM votes v WHERE
v.assertion = '$ID' ON DUPLICATE KEY UPDATE
rank = ( CASE WHEN v.vote = '1' THEN rank+50 WHEN v.vote = '-1'
THEN rank-200 WHEN v.vote = '3' THEN rank+100 ELSE rank END)"
applied on a database with a table users with and id and rank field, and a votes table with a user and vote field. I have to update the rank of the users in the users table based on their vote.
I really like this kind of query, but I've noticed a problem: every time I execute this from my PHP script the query adds a row to the users table completely empty (with only an ID, which is A_I, and a rank of 1, when usually there would be other field as well). I can't really wrap my head around why this happens.
Any help/idea?

Your table does not have a primary key first provide a primary key to id
run this sql query
alter table user add primary key (id)
and than try it will work

There are two possible reasons :
The id column is not the primary key, and probably you table doesn't have a primary key at all.
Create a primary key like this :
alter table user add primary key (id)
If you insert an value of 0 in an auto increment column, a new id is generated. An auto incremented column must not contain the value 0.
There is also a more general problem with your approach : in fact you only insert the user id and the rank, other compulsory fields in the table (username) are missing. The insert part does not seem to be valid for this reason. If you use an insert on duplicate key update, you must make sure that the result is correct which ever of insert and update is executed.

Related

PHP/SQL/Mysql/phpmyadmin - Foreign Keys

I'm building a shop for school purposes. I have finished my shop but i didn't joined tables and used foreign keys (requirement) because i forgot..
I have a newbie 'question' about foreign keys.
PRODUCTS RATING TABLE:
rate_id (id of the rate),
rate, (stars 0 to 5)
comment (user input textarea),
user_id (id of the user who commented the product),
product_id (id of the product that was commented)
USERS TABLE:
`id` (id of the user),
`email` (email of the user),
`name` (name of the user),
`age`,
`username`,
`password`,
`profile_pic`,
`role` (ADMIN/USER)ยด
When i enter a comment on X product (if (isset($_POST['comment_rating])):
$sql = mysqli_query($link, "SELECT id FROM users WHERE username='$user_id'");
and then later:
$sql = "INSERT INTO products_rating (rate, comment, user_id, product_id)
VALUES ('$rate_text', '$comment', '$user_id', '$product_id');
FINAL: What i want to know is, what do i need to change in my code if i add a foreign key? And should i add a foreign key in this particular case? I must interligate all tables, and I don't understand much about joins / foreign keys. If i wasn't clear let me know. Thank you for you help!
The idea of a foreign key is pretty straightforward.
In the products_rating table, we are storing a value for user_id.
And the value that we stored there is a value of id column from a row in the user table. This establishes a relationship between the row in products_rating an a row in user.
We could get the name and email address of the user that left a product rating
SELECT u.name
, u.email
, r.rate
, r.comment
FROM product_rating r
JOIN user u
ON u.id = r.user_id
WHERE ...
A FOREIGN KEY is a constraint that implements a rule. The rule we want to implement is that we want to allow only valid user.id values to be stored in product_rating.user_id.
For example, if we attempt to store a value of '42' in the product_rating.user_id column, the database is going to check that the value '42' appears in a row in the user table (in the id) column.
The syntax that we use to implement that constraint would be on the product_rating table:
ALTER TABLE `product_rating`
ADD CONSTRAINT -- we are adding a constraint
`FK_product_rating_user` -- the name we assign to the constraint
FOREIGN KEY -- the type of constraint
(`user_id`) -- the column(s) in this table
REFERENCES -- refer to
`user` -- the name of the "foreign" table
(`id`) -- the column(s) in the "foreign" table
We can add some additional configuration that affects behavior...
ON DELETE RESTRICT
ON UPDATE CASCADE
This implements a rule... if we attempt to assign a value to user_id column in this table, and that value is not found in a row in user table id column, an error is thrown, and the statement fails.
This rule also says that if we attempt to remove a row from user, if there are any rows in product_rating that have a user_id value that matches the id value of the row we're deleting, an error is thrown, and the statement fails.
The rule also says that we update a row in user, and assign a new value to the id column, than any rows in product_rating that have a user_id value that matches the old id value will be updated, to assign the new id value to the user_id column... preserving the relationship between the rows.
Also note that this implies a "one-to-many" relationship. A user can be related to zero, one or more product_rating. A product_rating is associated with one user. (If the user_id column allows for NULL values to be stored, a NULL value represents that the row in product_rating is not associated with any user.)
That's just a rough overview of FOREIGN KEY constraints.
The basic idea is that we establish a relationship between rows by storing a common value. In the example we use, a common value of '42' in the id column of a row in the user table, and in the user_id column of one (or more) row(s) in the product rating table.
With no foreign key constraint defined, the database allows us to store any value in the user_id column. We could store '43' or '8670', and it doesn't matter if those values appear in user.id or not.
The foreign key we defined constrains (restricts) what values we can store in the user_id column. When we attempt to add or modify a row in product_rating, the database checks the value of the user_id column, and if a non-NULL value doesn't reference a row in user, an error is raised.
Note that the foreign key constraint does not cause the user_id column to be automatically populated. If we want to establish a relationship to a row in user, we have to supply a value for user_id.

mysql insert and update table with max 3

I have a php script that logs inputs from a form into a mysql database table. I'm looking for a way to insert this data untill 3 rows are created, after which it has to update the existing rows so that the first one updates to the new input, the second one to the former first input and the third one to the former second input.
Table:
CREATE TABLE IF NOT EXISTS inputlog (
id int(11) NOT NULL auto_increment,
userid int(11) NOT NULL default '0',
name text,
value text,
PRIMARY KEY (id)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;`
For the first three rows i use:
insert into inputlog (userid,name,value) values('$userid','$name','$value')
After that is has to become:
update inputlog set value = '$value' where userid = '$userid' and name = '$name'
where it has to update all the successive rows.
How can i accomplish this?
Too long for comments, so...
Looks like you want to have only 3 rows in your table because you want the data to be sorted by the id. So id=1 will be the latest value, then id=2 and finally id=3.
In short, do not do that, the id field can be any value. Do not code for that. The danger is if you use the id in another table as a foreign key, you will loose referential integrity. What I propose is:
Add an timestamp column for each row.
Every time you insert a new value, set the timestamp column to NOW()
When selecting, sort on the timestamp and limit to 3 results
If you MUST have only 3 rows, you can then delete the row except for the 3 most recent timestamps.
But... if you must do that...
perform a SELECT with the first 2 lines
truncate the table (delete all rows)
insert the new line, then the 2 stored lines
You will then ahve your 3 rows in the order you want. But without seeing the entire reasoning for your application, my "spider sense" tells me you will hit a wall later on...
And check the comments for other things to worry about.

How to avoid duplicate on insert of field values in mysql

Good day guys, I have a grade/score table in MySql that students record will be inserted into using php. I want to avoid a student having a score repeated for a term/period. What I mean is that a student cant have two(2) grades/scores for a subject(mathematics) in a term(periodOne) table. How do I accomplish this in MySql or php? here is how my table looks:
table periodOne (
id int AUTO_INCREMENT,
studentId int,
subjectId int,
score
)
Let me know if you need extra information. Thanks!!!!!!
you have to add a unique contraint in mysql like this : ALTER TABLE periodOne ADD CONSTRAINT uc_check UNIQUE(studentId, subjectId). You will also have to check with PHP that there is no existing row before to do your INSERT
You can declare the attribute as "Unique" by using UNIQUE CONSTRAINT for which you don't want duplicate value.
If your score are dependent on some other table also then you can use Composite Primary Key.

Using ON DUPLICATE KEY UPDATE with 2 keys

I have a table with columns id, user_id, post_id, like, views. When a user click the Like button, a row will be added to the table with the corresponding user_id and post_id, and like will be set to 1. If the row already exist and the like column already is 1, nothing will happen.
When the user visits a particular page, a row will be added to the table with the corresponding user_id and post_id, and view will be set to 1. However if the row already exist, the value in view will be incremented.
Problem: I tried using INSERT INTO mytable ... ON DUPLICATE KEY UPDATE like = 1, but the primary key of the table is id and not user_id or post_id. If I set the primary key to either user_id or post_id, there will be a problem because the row will only be duplicated if there exist a row with the same user_id and post_id.
In this situation, how should the query be built?
Or will a better situation be to split the table into 2 tables, one for likes and 1 for views. If this is the case, I still need to make the row unique based on both user_id and post_id columns.
Or do multiple SQL queries?
Please advise, thanks!
I would suggest that you have a table for likes, and then in whatever table that you keep posts in, you add a row for views. So whenever this post is viewed, you simply update the view value for that post to view = view + 1.
Now to address the problem that you outlined about the primary keys, you should note that you can use a unique key in that scenario, which can apply to multiple columns and would fix the issue that you ran into. So for example if in your scenario you had a unique key that encompassed both the userid and postid, your database would not allow for two different rows in that table with the same userid and postid.
So for future reference, use a unique key if you need to :)
discard the id as primary key
use two tables
make primary key on (user_id, post_id)
when handle insert like, do a insert ignore
when handle insert view, do a insert .. duplicate key update view = view+1

MySQL update if the person exists

what would the MySQL query be to update a record if the record exists in the table i'm trying to update.
so for instance, i'm trying to set a certain column to blank if the record is in the table. if the record is not in the table, i just don't want it to do anything.
i'm using php and mysql
First, you'll need some sort of unique identifier for the record. This can be a PRIMARY KEY, a UNIQUE constraint, or similar. Let's say your users have a username that is guaranteed to be unique.
You can constrain your UPDATE query to only affect rows that have that username. So if the username doesn't exist, nothing will be done.
UPDATE `tbl_users` SET `target_field` = NULL WHERE `username` = "joebloggs";
you can look for the id of the existsing record and update that like this :
Update tbl_name set field_name=new_data
where id_column = (select id_column from tbl_name where key_column=key_value)

Categories