It is not as easy as the title itself. I have a table users which has a field assignedlessons. Data stored in this field is like 69|308|50|91. As you may have already know, it keep several lessons of a user has at the same time. What I am going to do is to export data from this field along with user_id and import to another newly created table user_assigned_elearning_lessons. The structure of this table is: id, user_id, elearning_lesson_id, created_at. After the importing, the structure in the new table should be like this:
id user_id elearning_lesson_id created_at
1 1 69 2011-01-12
2 1 308 2011-04-11
3 2 50 2011-05-18
4 3 91 2011-05-21
5 3 50 2011-07-18
6 3 308 2011-07-18
How do I do that?
Probably you'll want to look into using INSERT ... SELECT FROM syntax. Without full details of the source and destination tables, we can't help beyond that.
Despite what others have suggested, you can't do what you want with INSERT ... SELECT syntax, because you've to split values and insert more than one row for each row of the source table.
You can instead write a short PHP script to do the job, I've assumed the following table structure and test data:
CREATE TABLE IF NOT EXISTS `users` (
`user_id` int(11) NOT NULL,
`assignedlessons` varchar(100) NOT NULL,
PRIMARY KEY (`user_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
INSERT INTO `users` (`user_id`, `assignedlessons`) VALUES
(1, '69|308|50|91'),
(2, '56|34|7');
CREATE TABLE IF NOT EXISTS `user_assigned_elearning_lessons` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` int(11) NOT NULL,
`elearning_lesson_id` int(11) NOT NULL,
`created_at` date NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=8 ;
With a PHP script you can loop over all the rows of the first table, explode the composite field into its parts and do an INSERT statement for each of those part. I've used mysqli object oriented style with prepared statements to build the insert queries.
<?php
main();
function main() {
$source = new mysqli("localhost", "username", "password", "database");
$destin = new mysqli("localhost", "username", "password", "database");
$stmt = prepareInsertStatement($destin);
$result = $source->query("SELECT user_id, assignedlessons FROM users");
while ($user = $result->fetch_object()) {
insertUser($stmt, $user);
}
$result->close();
$source->close();
$destin->close();
}
function insertUser(&$stmt, &$user) {
$lessons = explode('|', $user->assignedlessons);
foreach ($lessons AS $lesson) {
$stmt->bind_param("ii", $user->user_id, $lesson);
$stmt->execute();
echo "User " . $user->user_id . " lesson $lesson<br/>";
}
}
function &prepareInsertStatement(&$destin) {
$sql = "INSERT INTO user_assigned_elearning_lessons
(user_id, elearning_lesson_id, created_at) VALUES (?, ?, NOW())";
$stmt = $destin->stmt_init();
$stmt->prepare($sql);
return $stmt;
}
?>
I bind the parameters to the the prepared statement with bind_param:
$stmt->bind_param("ii", $user->user_id, $lesson);
Where the "ii" means that the type of those parameters is integer and integer.
The output with this test data will be:
User 1 lesson 69
User 1 lesson 308
User 1 lesson 50
User 1 lesson 91
User 2 lesson 56
User 2 lesson 34
User 2 lesson 7
You could use syntax like:
INSERT INTO tbl2 (col1, col2, col3, ....)
SELECT col1, col2, col3
FROM tbl1
or check http://dev.mysql.com/doc/refman/5.1/en/insert-select.html for further details.
Related
I set 3 columns: id(auto increment), names, age(default = 15).
Now if I want to insert data to SQL I can use this below line:
INSERT INTO shoppinglist (name,age) VALUES(?,?)
The first ? = alex and second ? = 22
which will find in the database that the id=1, the name=alex and age=22
Now what I want that if the user inserts only the name without the age, I would like from the age to get the default value, like if the user insert only the name with David, and submit it, I would like to e in DB like id=2 name =David age=15(default)
So is there a way to make the age to get the default if the user didn't insert the age or the age was 0?
create shoppinglist (
`id` int NOT NULL AUTO_INCREMENT,
`name` varchar(45) DEFAULT NULL,
`age` int default 15
)
when you make the insertion, it would be like this:
INSERT INTO shoppinglist (name) VALUES ("Alex");
Or
INSERT INTO shoppinglist VALUES (Null, "Alex", DEFAULT);
INSERT INTO shoppinglist (name) VALUES(?)
this query inserts just name and puts the default value 15 for the age
You can use IFNULL function in query:
INSERT INTO shoppinglist (name,age) VALUES(?, IFNULL(?, 15));
The PHP code may look as:
$query = "INSERT INTO shoppinglist (name,age) VALUES(?, IFNULL(?, 15));";
$stmt = $pdo->prepare($query);
$stmt->execute(['Alex', 30]);
$stmt->execute(['Jane', null]);
PHP PDO online fiddle
I am trying to develop a rating system with php/mysql.
I have a simple rating object like this:
(t is type of rating, r is value of rating)
[{"t":"1","r":2},{"t":"2","r":4},{"t":"3","r":1},{"t":"4","r":2},{"t":"5","r":2}]
In DB, I have a lot of rating records
Like this:
object1=> [{"t":"1","r":2},{"t":"2","r":4},{"t":"3","r":1},{"t":"4","r":2},{"t":"5","r":2}]
object2=> [{"t":"1","r":1},{"t":"2","r":5},{"t":"3","r":3},{"t":"4","r":3},{"t":"5","r":1}]
In short for output I need a new object like this (I need to calculate average rating, with same keys.)
objectAverageCalculated=> [{"t":"1","r":1.5},{"t":"2","r":4.5},{"t":"3","r":2},{"t":"4","r":2.5},{"t":"5","r":1.5}]
My sql:
CREATE TABLE `ratings` (
`id` int(11) NOT NULL,
`rating` text NOT NULL,
`item_id` varchar(16) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
INSERT INTO `ratings` (`id`, `rating`, `item_id`) VALUES
(6, '[{\"t\":\"1\",\"r\":2},{\"t\":\"2\",\"r\":4},{\"t\":\"3\",\"r\":1},{\"t\":\"4\",\"r\":2},{\"t\":\"5\",\"r\":2}]', 'ABC123'),
(7, '[{\"t\":\"1\",\"r\":1},{\"t\":\"2\",\"r\":5},{\"t\":\"3\",\"r\":3},{\"t\":\"4\",\"r\":3},{\"t\":\"5\",\"r\":1}]', 'ABC123');
--
ALTER TABLE `ratings`
ADD PRIMARY KEY (`id`);
ALTER TABLE `ratings`
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=8;
COMMIT;
My code
$result = mysqli_query($con, "SELECT * FROM ratings WHERE item_id='ABC123' ");
while ($row = mysqli_fetch_array($result)) {
$tempArray = json_decode($row['rating'], true);
array_push($ratingsRaw, $tempArray);
}
I can not save every object with new variable (like $item1,$item2, etc...)
How can I store every object in one array and how can I get average of every rating type in one output object?
You can use AVG() method in your MySQL query and retrieve average value directly from database.
SELECT AVG(rating) AS avg_rating FROM ratings WHERE item_id='ABC123'
Or when you don't specify ID and you want average value for all items.
SELECT AVG(rating) AS avg_rating, item_id FROM ratings GROUP BY item_id
This question already has an answer here:
MySQL SELECT LAST_INSERT_ID() for compound key. Is it possible?
(1 answer)
Closed 6 years ago.
I have this table:
CREATE TABLE `test` (
`Id1` int(11) unsigned NOT NULL,
`Id2` int(11) unsigned NOT NULL,
`Id3` int(11) unsigned NOT NULL,
`Id4` int(11) unsigned NOT NULL AUTO_INCREMENT,
`Name` varchar(255) NOT NULL,
PRIMARY KEY (`Id1`,`Id2`,`Id3`,`Id4`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 ROW_FORMAT=DYNAMIC;
INSERT INTO `test` (`Id1`, `Id2`, `Id3`, `Name`) VALUES (1, 1, 1, 'test')
INSERT INTO `test` (`Id1`, `Id2`, `Id3`, `Name`) VALUES (1, 1, 1, 'test2')
INSERT INTO `test` (`Id1`, `Id2`, `Id3`, `Name`) VALUES (1, 2, 1, 'test')
INSERT INTO `test` (`Id1`, `Id2`, `Id3`, `Name`) VALUES (1, 2, 1, 'test2')
After creating the table the date looks like this:
Id1 Id2 Id3 Id4 Name
1 1 1 1 test
1 1 1 2 test2
1 2 1 1 test
1 2 1 2 test2
Id4 is incrementing as is expected but I have problem to get inserted Id4 using PHP mysqli. This is the code I am using:
$db = new mysqli('host', 'user', 'pass', 'db');
$db->query("INSERT INTO `test` (`Id1`, `Id2`, `Id3`, `Name`) VALUES (1, 1, 1, 'test')");
var_dump($db->insert_id);
I get result
int(0)
Result should be int(1) but I get zero for no reason. Any ideas?
Essentially, your code should work... it worked when tested... in other words check to see if there is something else going on... as it stands, your code is ok.... and should work fine... However as an alternative work-around, you may want to wrap MySql LAST_INSERT_ID() Function in your own Function and then call the Function when you need to get the Last Insert ID...
<?php
// WILL RETURN THE ID OF THE AUTO-INCREMENTED FIELD ONLY
function getLastInsertID($db, $tbl='test'){
$result = null;
$sql = $db->prepare("SELECT LAST_INSERT_ID() FROM `". $tbl ."`");
$sql->execute();
$sql->bind_result($result);
$sql->fetch();
return $result;
}
var_dump(getLastInsertID($db));
Perhaps it does the Trick for you....
REF: http://dev.mysql.com/doc/refman/5.7/en/getting-unique-id.html
LAST_INSERT_ID() returns the value only for a column declared AUTO_INCREMENT. There's no function to return the value in a compound primary key that wasn't generated by the system. You ought to know that value already, since you just gave it in an INSERT statement. The tricky case would be when a trigger or something overrides the value.
More details:
Check this stackoverflow link
I am studying relational databases on my own and after reading some articles I am having trouble implementing them.
Due to my lack of experience with relational databases I believe that my error can be in any of the following 3 (if not in all 3) steps:
Table Creaton
Value Insertion
Query call
I should point out that there aren't any syntax errors or something like that.
We are talking about an error in my understanding so I will approach the problem in detail.
The tables:
For the abstraction I have chosen to have people and the drinks which they like (1 person can like many drinks, one drink can be liked by many people.
Here is the code for the table People (It has 2 names, and a primary key):
CREATE TABLE `People`
(
`PeopleID` INT NOT NULL AUTO_INCREMENT,
`FirstName` VARCHAR(25),
`LastName` VARCHAR(25) NOT NULL,
PRIMARY KEY (`PeopleID`)
)
Here is the table Drinks (Name of drink, some number in menu or something like that for example and the primary key)
CREATE TABLE `Drinks`
(
`DrinksID` INT NOT NULL AUTO_INCREMENT,
`Code` VARCHAR(10) CHARACTER SET ascii COLLATE ascii_general_ci NOT NULL,
`Name` VARCHAR(100) NOT NULL,
PRIMARY KEY (`DrinksID`)
)
And lastly the table PeopleDrinks:
CREATE TABLE `PeopleDrinks`
(
`DrinksID` INT NOT NULL default 1,
`PeopleID` INT NOT NULL default 1,
PRIMARY KEY (`DrinksID`,`PeopleID`)
)
Note: from here I saw the example given for the third table and pretty much copied it.
Value insertion:
People input:
INSERT INTO People (FirstName, LastName) VALUES ('John', 'Smith')
INSERT INTO People (FirstName, LastName) VALUES ('Sam', 'Johnson')
INSERT INTO People (FirstName, LastName) VALUES ('Michael', 'Morgan')
Drinks input:
INSERT INTO Drinks (Code, Name)VALUES ('#543', 'Beer')
INSERT INTO Drinks (Code, Name) VALUES ('#132', 'Vodka')
INSERT INTO Drinks (Code, Name) VALUES ('#123', 'Wine')
PeopleDrinks input:
Note: The id of the drinks are 4, 5 and 6. Not 1, 2, 3.
INSERT INTO PeopleDrinks (DrinksID, PeopleID) VALUES (1, 4)
INSERT INTO PeopleDrinks (DrinksID, PeopleID) VALUES (2, 5)
INSERT INTO PeopleDrinks (DrinksID, PeopleID) VALUES (3, 6)
Above we give as favorite one drink to every person. Below we will make one person like all the drinks:
INSERT INTO PeopleDrinks (DrinksID, PeopleID) VALUES (1, 5)
INSERT INTO PeopleDrinks (DrinksID, PeopleID) VALUES (1, 6)
And finally the query call:
//Consider $link an established, working connection to the database
$result = mysqli_query($link, "SELECT
`People`.*
FROM
`People`
JOIN
`PeopleDrinks` ON `People`.`PeopleID` = `PeopleDrinks`.`PeopleID`
WHERE
`PeopleDrinks`.`DrinksID` = 5");
while($row = mysqli_fetch_array($result))
{
echo $row['FirstName'] . " " . $row['LastName'];
echo "<br/>";
}
The above code, should print the name of anyone who likes the drink with id 5. I don't get an error, but I don't get any output.
You said the id of the drinks are 4,5,6
In the INsert you have used
INSERT INTO PeopleDrinks (DrinksID, PeopleID)VALUES (1, 4)
INSERT INTO PeopleDrinks (DrinksID, PeopleID) VALUES (2, 5)
INSERT INTO PeopleDrinks (DrinksID, PeopleID) VALUES (3, 6)
The drink ids(first number) are 1,2,3 instead of 4,5,6 or something like that. I think your order is wrong.
Your many to many table needs foreigns key :
CREATE TABLE `PeopleDrinks` (
`DrinksID` INT NOT NULL,
`PeopleID` INT NOT NULL,
PRIMARY KEY (`DrinksID`,`PeopleID`),
FOREIGN KEY (`DrinksID`) REFERENCES `Drinks`(`DrinksID`),
FOREIGN KEY (`PeopleID`) REFERENCES `People`(`PeopleID`)
)
Remove the default values of DrinksID and PeopleID, this make no sense.
Then when you do your insert, you will be sure that the data you are trying to insert are right.
I think that your insert are false. When you say that your IDs are what they are, you are wrong. This is particulary true if your are doing a lot of inserts and deletes. Autoincrement will keep going forever, and you can't be sure. With Foreign Keys, the RDBMS will tell you if there is something wrong with your relations.
Anyway, your query looks great, so no problem for that.
I've got a form on my website for users to input their fname, sname, company,phone,email which then gets updated to a database on submit. I also have a field in my database for a unique userID to incase users have same name and company ect. When submitting my form how is it possible to add in this field, a unique number so that it is +1 from the fields taken already. At the minute there are only 3 userIDs so i need the next inputted one to be 4 and so on.
At the moment I have this.
require_once('dbConnect.php');
//taken from a smarty template form.
$addForename = $_POST['forename'];
$addSurname = $_POST['surname'];
$addCompany = $_POST['company'];
$addContact = $_POST['contact'];
$addEmail = $_POST['email'];
public function addUser($addForename,$addSurname,$addCompany,$addContact,$addEmail)
{
$sql = "INSERT INTO `Users` (`Forename`, `Surname`, `ComanyName`, `Phone`, `Email`) VALUES ('".$addForename."','".$addSurname."','".$addCompany."','".$addContact."','".$addEmail."')";
$databaseAccess = new DatabaseConnect();
try
{
$result = $databaseAccess->connect($sql, "add");
}
catch (Exception $e)
{
throw new Exception("Adding User Failed !!!");
}
if ($result)
{
return 1;
}
else{return 0;}
}
thanks
If you are using phpmyadmin there should be a checkbox when youre creating a new column with "A_I" or Auto_Increment.. you have to check that and then it will count your entrys.
Create the row as an auto_increment in the database:
create table someName (ID int primary key auto_increment, col1 int ...);
Then when you are inserting data, either pass it a null, or don't insert that field like this:
insert into someName (col1) values (3);
or
insert into someName (ID, col1) values (null, 3);
You can modify your current table with the following:
ALTER TABLE someName MODIFY COLUMN ID INT NOT NULL AUTO_INCREMENT , ADD PRIMARY KEY (ID);
create the ID:
ALTER TABLE users ADD ID INT UNSIGNED
NOT NULL AUTO_INCREMENT, ADD PRIMARY KEY (ID);
and start the auto-increment where you want
ALTER TABLE tbl AUTO_INCREMENT = 4;
Create a column set it as a primary key and auto increment. You can even write a stored procedure for inserting in the table. That way you don't have to write query every time and not have to worry about escape characters. If you want the particular no to be returned from stored procedure use SCOPE_IDENTITY() in the stored procedure.