Table_A
+--------+-----------+---------+
| id | name | views |
+--------+-----------++--------+
| num | text | int |
+--------+-----------+---------+
| 1 | Video 1 | 10 |
| NULL | NULL | 0 |
| NULL | NULL | 0 |
| NULL | NULL | 0 |
| NULL | NULL | 0 |
+--------+-----------+---------+
<a href="video.php?id=video1&idtitle=Hello%20Video1">
<a href="video.php?id=video2&idtitle=Hello%20Video2">
<a href="video.php?id=video3&idtitle=Hello%20Video3">
I'm trying to make the script do something like this.
1.User click on link
2.User is on video.php?id=video1
3.Mysql then add a +1 to my id column #1
4.then take the video title from $videoName
5.Mysql take the title inside of $videoname and store it on name column #2
6.Mysql then add +1 to Views everytime ID 1 is view
7.Mysql is now finish with Row 1
8.Now Mysql will repeat that same step if video.php?id=video2 and so on,
How can i make this happen?
$id = $_GET['id'];
$videoName = $_GET['idtitle'];
$pdo = new PDO('mysql:localhost;dbname=videocount', 'root', '');
$userip = $_SERVER["REMOTE_ADDR"];
if($userip){
$pdo->query("UPDATE Table_A SET (`id`, `name`, `views`)
VALUES (NULL,$videoName, views+1)");
}
I also try the code below but still no luck.
if($userip){
$pdo->query("INSERT INTO `videocount`.`Table_A` (`id`, `name`, `views`)
VALUES (NULL, '$videoname', 'views'+1)");
}
UPDATE instead of UPDATED, VALUES instead of VALUE. In addition you have to add a WHERE condition to your query to select record to update.
This is another correct syntax:
$pdo->query( "UPDATE `Table_A` SET `views`=`views`+1 WHERE `id`='$id'" );
Edit:
To update also the video name you can perform this query:
$pdo->query( "UPDATE `Table_A` SET `name`='{$videoName}', `views`=`views`+1 WHERE `id`='$id'" );
On the border, you should bind the variable values to avoid errors with titles special characters.
See more about binding and MySQL UPDATE syntax
I think there is a little confusion about data view logic.
First of all, you need to save all data into database, then list them for user.
When the use click the link to view this video, the column of views need to be updated.
Related
I use mysql and php with phpmyadmin. I have major problem with a partition based counter that I wan't to improve but my knowledge on sql prevents me from doing that. Im struggling very much with this.
I want the duplicated data in my table to have a counter that adds a number after a value if this value gets a duplicated value and then restarts from 1 until a new value is met and so on. Here is what the final result should look like
---------------------------
1 | Josh-1
---------------------------
2 | Josh-2
--------------------------
3 | Josh-3
--------------------------
4 | Josh-4
--------------------------
5 | Fred-1
--------------------------
6 | Fred-2
--------------------------
7 | Fred-3
-------------------------
I had gotten help with this counter here before but it's not working as I wan't it to. Also when I have pressed the insert button in my form the table looks like this in phpmyadmin after I reload it
---------------------------
1 | Josh-1-1-1
---------------------------
2 | Josh-2
--------------------------
3 | Josh-3
--------------------------
4 | Josh-4
--------------------------
5 | Fred-1
--------------------------
6 | Fred-2
--------------------------
7 | Fred
-------------------------
Whats going on here? The code that I seek help with rewriting is this
UPDATE usermeta u1,
(SELECT
u1.`id`, CONCAT(u1.`name`,'-',ROW_NUMBER() OVER(PARTITION BY u1.`name` ORDER BY u1.`id`)) newname
FROM
usermeta u1 JOIN (SELECT `name` , COUNT(*) FROM usermeta GROUP BY `name` HAVING COUNT(*) > 1) u2
ON u1.`name` = u2.`name` ) u3
SET u1.`name` = u3.`newname`
WHERE u1.`id` = u3.`id`
Could this code be rewritten so it creates a table of numbered names and duplicates that looks like the first table example and work like it should in phpmyadmin ? All help is very much appreciated. Keep in mind that I am a struggling moderate sql user.
Possible solution - BEFORE INSERT trigger and additional MyISAM table with secondary autoincrement:
Working table
CREATE TABLE user (id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(127));
Additional table
CREATE TABLE user_index (id INT AUTO_INCREMENT,
name VARCHAR(127),
PRIMARY KEY (name, id)) ENGINE=MyISAM;
Trigger
CREATE TRIGGER insert_user_index
BEFORE INSERT ON user
FOR EACH ROW
BEGIN
DECLARE new_index INT;
INSERT INTO user_index (name) VALUES (NEW.name);
SET new_index = LAST_INSERT_ID();
DELETE FROM user_index WHERE name = NEW.name AND id < new_index;
SET NEW.name = CONCAT_WS('-', NEW.name, new_index);
END
Insert rows - the AI index is added to the name. Check the result.
INSERT INTO user (name) VALUES
('Josh'),
('Josh'),
('Fred'),
('Josh'),
('Fred'),
('Fred'),
('Josh');
SELECT * FROM user;
id | name
-: | :-----
1 | Josh-1
2 | Josh-2
3 | Fred-1
4 | Josh-3
5 | Fred-2
6 | Fred-3
7 | Josh-4
Look what is stored in additional table now.
SELECT * FROM user_index;
id | name
-: | :---
3 | Fred
4 | Josh
db<>fiddle here
If your working table user exists already, and it contains some data, then you'd create additional table and fill it with data using, for example,
CREATE TABLE user_index (id INT AUTO_INCREMENT,
name VARCHAR(127),
PRIMARY KEY (name, id)) ENGINE=MyISAM
SELECT MAX(SUBSTRING_INDEX(name, '-', -1) + 0) id,
SUBSTRING_INDEX(name, '-', 1) name
FROM user
GROUP BY 2;
https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=38f028cfe1c9e85188ab0454463dcd78
want insert a duplicate entry into mysql with a suffix. here is an example:
+-------+--------------+-------+
| ID | Title | url |
+-------+--------------+-------+
+-------+--------------+-------+
| 1 | test | test1 |
+-------+--------------+-------+
| 2 | test | test2 |
+-------+--------------+-------+
| 3 | test | test3 |
+-------+--------------+-------+
means, i want to add auto number as suffix to end of each url that have duplicate title. titles are duplicated but url are kinda unique.
Here is query:
$i = 0;
$i++;
$sql = "INSERT INTO `content` (title, text, cat, url, tag)
VALUES ('".$_POST["title"]."', '".$_POST["text"]."', '".$_POST["category"]."', '".$_POST["url"]."', '".$_POST["tag"]."') ON DUPLICATE KEY UPDATE url=".$_POST["url"]."+". $i ."";
note: url made dynamically based on title entry.
this query not working, what is wrong with my code?
UPDATE: here is error after run query:
error: INSERT INTO content (title, text, cat, url, tag) VALUES
('test', '', '16', 'test', '') ON DUPLICATE KEY UPDATE url=test+1
Unknown column 'test' in 'field list'
Your code has some strange things. $i = 0; followed by $i++; is just equivalent than doing $i = 1; But then again, what's the purpose on setting a variable that you only use once?
What you really need to do is:
INSERT query forgetting about the "url" field and removing the ON DUPLICATE...
Get the ID of the last insert. Have a look at the following link to see how to get that value: http://www.w3schools.com/php/php_mysql_insert_lastid.asp
UPDATE query to set the value of "url"
$_POST["url"].$id_of_last_query
I have this table called classes:
+------------+----------+------+-----+----------------+
| Field | Type | Null | Key | Extra |
+------------+----------+------+-----+----------------+
| class_id | int(3) | NO | PRI | auto_increment |
| class_level| int(1) | YES | | |
| class_name | char(1) | YES | | |
+------------+----------+------+-----+----------------+
With data inside like this:
+----------+-------------+------------+
| class_id | class_level | class_name |
+----------+-------------+------------+
| 1 | 0 | N |
| 2 | 1 | A |
| 3 | 1 | B |
| 4 | 2 | C |
| 5 | 2 | D |
| 6 | 3 | E |
| 7 | 3 | F |
+----------+-------------+------------+
With PHP I want to increment all values inside class_level except 0.
So I made this PHP/MySQL function:
mysql_query("UPDATE classes SET class_level = (class_level + 1) WHERE class_level != 0") or die(mysql_error());
This (what is weird) does not add 1 to each class_level except theese equal to 0, but adds 2 or 3 or 4! I haven't found a rule, that this script would add either 2 or 3 or 4. This is RANDOMLY picked. And there is no error outputted too.
All it does it adds randomly 2 or 3 or 4 to each row.
So, to debug it, I have done this PHP code to add to each one by one:
$query = mysql_query("SELECT * FROM `classes` WHERE `class_level` != 0");
while ($row = mysql_fetch_assoc($query)) {
$class_id = $row['class_id'];
$class_level = $row['class_level'];
$class_level = $class_level + 1;
var_dump($class_level);
mysql_query("UPDATE `classes` SET `class_level` = '$class_level' WHERE `class_id` = '$class_id'") or die(mysql_error());
}
The output from var_dump is:
int(2) int(2) int(3) int(3) int(4) int(4)
But in database in table I get following result:
+----------+-------------+------------+
| class_id | class_level | class_name |
+----------+-------------+------------+
| 1 | 0 | N |
| 2 | 4 | A |
| 3 | 4 | B |
| 3 | 5 | C |
| 4 | 5 | D |
| 5 | 6 | E |
| 6 | 6 | F |
+----------+-------------+------------+
This is an empty file with just MySQL connection and the code above, so there is no loop above it.
Here is my version information: PHP version: 5.2.12, MySQL Client API version 5.1.44. Note that I cannot install mysqli nor PDO.
EDIT:
Just after executing the MySQL query I have outputted data from table, and the result was, as it should be. But in table itself (or on refresh with code just for output) there was 3 added, not 1!
EDIT 2:
I tried executing this MySQL query from command line (aka Webmin tool for SQL commands) and the result was, as it should be: 1 was added.
EDIT
Added SQL Fiddle demonstration: http://sqlfiddle.com/#!9/efa05b/1
create table classes
( class_id int(3) not null auto_increment primary key comment 'pk'
, class_level int(1)
, class_name char(1)
)
;
insert into classes (class_id,class_level,class_name) values
('1','0','N')
,('2','1','A')
,('3','1','B')
,('4','2','C')
,('5','2','D')
,('6','3','E')
,('7','3','F')
;
update classes set class_level = (class_level + 1) where class_level != 0
;
A query verifies that expected result is returned. Each row (other than row with class_level=0) has been updated, with class_level incremented by exactly 1.
select * from classes order by class_id
class_id class_level class_name
-------- ----------- ----------
1 0 N
2 2 A
3 2 B
4 3 C
5 3 D
6 4 E
7 4 F
original answer
Assuming that there isn't a BEFORE/AFTER UPDATE trigger on the table, given the SQL statement being executed:
UPDATE classes SET class_level = (class_level + 1) WHERE class_level != 0
The most logical explanation for the behavior is that the SQL statement is being executed multiple times within the function, or, the function is being called multiple times.
To verify this, you could temporarily turn on the MySQL general log, run the test, disable the general log, and review... and you're going to find multiple executions of the statement. If you don't have access to the MySQL server, then the next best would be to echo out a line immediately before the statement is executed; you're going to see that line echoed out multiple times.
Highly unlikely that this is a bug in the MySQL database. (Verify there isn't a TRIGGER defined on the table.)
Also, test that statement using a different client, like mysql command like client, or phpmyadmin. And verify the statement is working correctly.
FOLLOWUP
Given that your test of the SQL statement from a different client gives the expected results, I think this demonstrates this isn't a problem with the MySQL database or the SQL statement.
For some reason, that SQL statement is being executed multiple times. As a next step in debugging, I would add some more code. I'd temporarily create a "log" table, using MyISAM engine, containing an auto_increment id, a datetime column, and an informational string:
CREATE TABLE debug_log
( id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY
, dt DATETIME
, info VARCHAR(40)
) Engine=MyISAM
Then add another SQL statement in your function to insert a row to that table, immediately before and/or after the execution of the UPDATE statement
INSERT INTO debug_log (dt, info) VALUES (SYSDATE(), 'my function before update')
Then, run the test, and see how many rows get inserted into the debug_log table.
To get an error thrown if this statement is executed more than one time, supply a fixed value for the id column, e.g.
INSERT INTO debug_log (id, dt, info)
VALUES (123, SYSDATE(), 'my function before update')
With the fixed value for id, if that statement gets called a second time, then MySQL will throw a duplicate key exception.
As I mentioned previously, based on the information provided, I suspect that your function is being called multiple times. (I don't have sufficient information to actually make that determination; that's just a hunch.)
Here is the simple solution below
<?php
print("<h1>BEFORE</h1>");
$q =mysql_query("select *from classes ");
while($row=mysql_fetch_array($q)){
print("$row['class_id'] - $row['class_level'] - row[$class_name] <br/>");
}
mysql_query("UPDATE classes SET class_level = class_level+1 WHERE class_level>0") or die(mysql_error());
print("<h1>AFTER</h1>");
$q =mysql_query("select *from classes ");
while($row=mysql_fetch_array($q)){
print("$row['class_id'] - $row['class_level'] - row[$class_name] <br/>");
}
?>
You dnt need to write any single php line to do what you are actually want to do.
Ok i have updated the code try this way. First it will get data & show . Secondly ,it will update the data .finally,display the data. Try this way hope you can find your problem.
I solved this by simply doing something like this:
mysql_query("UPDATE classes SET class_level = 2 WHERE class_level = 1");
mysql_query("UPDATE classes SET class_level = 3 WHERE class_level = 2");
mysql_query("UPDATE classes SET class_level = 4 WHERE class_level = 3");
I have just those three classes so it gets the job done.
It isn't the way I wanted to go with, but it works. The bug was really odd and I'd rather not go back to it. I hope this helps someone though.
P.S. How could I possibly not think about that in the first place XD
I have a table that has the following records:
ID | Username | Selected |
----------------------------
1 | JamesC | 1 |
2 | MikeF | 0 |
3 | JamesC | 0 |
I wish to have Selected be true for only 1 row where the username is the same. So for example when I set ID = 3 to be Selected = true I wish to setID =1 to have Selected = false as well as any other ID's with the same username.
Right now i'm doing this,
//set all to 0
update table set selected = 0 where username = '$username'
//set unique row to true
update table set selected = 1 where username = '$username' and ID = '$ID';
Is there a better more concise way of achieving the same effect?
As it was said - not very nice db structure, it is better to have table with unique names and ID of selected item, anyway, you can go with this single query:
update table set selected=IF(id = '$ID', 1, 0) where username = '$username';
also, try a possible faster variant (test both via explain):
update table set selected=IF(id <> '$ID', 0, 1) where username = '$username';
It looks more like optimizing db structure to me. More info needed for concrete answer though, but check this example to see what I'm talking about:
users:
user_id | user_name | selected_character_id | ...other account data
1 | JamesC | 3
2 | MikeF | 2
characters:
character_id | user_id | ...other character data
1 | 1 |
2 | 2 |
3 | 1 |
You will need JOIN tables to retrieve all data for selected character (fast since it operates on unique ids), but get rid of data duplication (and easier switch).
You will always need the second statement, but as you only have one "Selected" row you could use:
update table set selected = 0 where selected = 1
How in php/mySQL can i make a column equal another column?
id is auto increment, xid should be unique. Can i make xid = id in SQL? (the reason for this is to log changes but i'll explain more if needed)
To make xid unique the best way is to copy the auto increment of id
+----+-----+----------+----------------+------+---------+
| id | xid | title | body | page | visible |
+----+-----+----------+----------------+------+---------+
| 1 | 1 | my title | my body | NULL | 1 |
| 2 | 2 | my title | my body edited | 1 | 0 |
+----+-----+----------+----------------+------+---------+
$queryX = "INSERT INTO table (xid, title, body, page, visible)
VALUES (, 'Plays', 'it's playing', 'book page', 1)";
I don't understand why you want to do this, but my approach would be using two queries and LAST_INSERT_ID():
INSERT INTO table (title, body, page, visible)
VALUES ('Plays', 'it''s playing', 'book page', 1);
UPDATE table SET xid = id WHERE id = LAST_INSERT_ID();
You may want to do this using a TRIGGER, so you don't have to do it manually.
In one query:
INSERT INTO table (xid, title, body, page, visible) VALUES
( SELECT MAX(xid) + 1, .... )
it will put unique xid, can be done with id also, I not quite sure I undestand the need...