I have messed up my database design a bit. This was the original schema:
CREATE TABLE IF NOT EXISTS `xeon_stats_clicks` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`typ` enum('1','2','3','4','5','6','7','8','9') COLLATE utf8_bin NOT NULL,
`user` varchar(20) COLLATE utf8_bin NOT NULL,
`data` varchar(10) COLLATE utf8_bin NOT NULL,
`value` varchar(20) COLLATE utf8_bin NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
UNIQUE KEY `typ` (`typ`,`user`,`data`),
KEY `data` (`data`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin AUTO_INCREMENT=1 ;
As you can see, I have KEY on the following:
UNIQUE KEY `typ` (`typ`,`user`,`data`),
KEY `data` (`data`)
I have the following code execute:
"INSERT INTO `xeon_stats_clicks` (typ, user, data, value) VALUES ('1', :username, :date, 1) ON DUPLICATE KEY UPDATE value = value + 1"
However, above code doesn't work now, as my table schema now look like this:
CREATE TABLE `xeon_stats_clicks` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`typ` enum('1','2','3','4','5','6','7','8','9') COLLATE utf8_bin NOT NULL,
`user` varchar(20) COLLATE utf8_bin NOT NULL,
`data` varchar(10) COLLATE utf8_bin NOT NULL,
`value` varchar(20) COLLATE utf8_bin NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
KEY `idx_value` (`value`),
KEY `idx_typ` (`typ`),
KEY `idx_data` (`data`),
KEY `idx_user` (`user`),
KEY `data` (`data`),
KEY `data_2` (`data`)
) ENGINE=MyISAM AUTO_INCREMENT=991799 DEFAULT CHARSET=utf8 COLLATE=utf8_bin
How can I revert the changes made, and return to the first schema without messing up the data in the table?
I have no idea why your first schema + code doesn't work.
It works for value that is integer:
http://sqlfiddle.com/#!9/c3260/1
INSERT INTO `xeon_stats_clicks` (typ, user, data, value) VALUES
('2', 'user2', 'data3', 1) ON DUPLICATE KEY UPDATE `value` = `value` + 1
But if you will try on fiddle to apply that query to other lines it doesn't work. Because mysql can't convert VARCHAR to INT.
My guess you have wrong data in value column. For the combination of (typ, user, data, value) that you test.
UPDATE Here is the fiddle with your second schema in use:
http://sqlfiddle.com/#!9/5ea62b/1
As you can see your query works fine as well if you add
UNIQUE KEY `typ` (`typ`,`user`,`data`),
to that second schema.
and here is ALTER TABLE variant that works as well:
http://sqlfiddle.com/#!9/57b409/1
UPDATE 2 Another guess: You have broken uniqueness in your table now.
If I got you correctly you had
UNIQUE KEY `typ` (`typ`,`user`,`data`),
when start the project. After a while you did remove that UNIQUE KEY from schema. That change allowed mysql to insert duplicate records into that table. And apparently you inserted several (or a lot) of duplicates. And now you want to apply ALTER TABLE to get back unique key but mysql refuse that because of that.
Like here: http://sqlfiddle.com/#!9/4cbb5 <-- uncomment ALTER line to see error message
So you need to fix uniqueness first.
UPDATE 3 Delete duplicates:
http://sqlfiddle.com/#!9/85f228/1
DELETE FROM xeon_stats_clicks USING xeon_stats_clicks
INNER JOIN xeon_stats_clicks dup
ON xeon_stats_clicks.id < dup.id
AND xeon_stats_clicks.typ = dup.typ
AND xeon_stats_clicks.user = dup.user
AND xeon_stats_clicks.data = dup.data;
Related
ERROR 1265: Data truncated for column 'profile_pic' at row 1
SQL Statement:
ALTER TABLE `student`.`student_info`
CHANGE COLUMN `profile_pic` `profile_pic` VARCHAR(50) NOT NULL DEFAULT 'images/profile.png'
ERROR: Error when running failback script. Details follow.
ERROR 1050: Table 'student_info' already exists
SQL Statement:
CREATE TABLE `student_info` (
`name` varchar(45) NOT NULL,
`email` varchar(45) NOT NULL,
`password` varchar(45) NOT NULL,
`profile_pic` varchar(500) DEFAULT 'images/profile.png',
PRIMARY KEY (`email`),
UNIQUE KEY `email_UNIQUE` (`email`),
UNIQUE KEY `password_UNIQUE` (`password`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
this error is flashing when i am setting the value of profile_pic column as not null however if i am not not doing so this error is not occurring can any body please explain me why is this error occurring and how to remove this
Change your Alter query to
ALTER TABLE `student`.`student_info`
CHANGE COLUMN `profile_pic` `profile_pic` VARCHAR(500) NOT NULL DEFAULT 'images/profile.png'
In your schema you have previously defined profile_pic with varchar(500) now you are trying to set it not null but with varchar(50) so your column contains the data which is longer than 50 characters therefore you see this truncated error
I'm trying to get this MySQL code to work, but it's saying 0 rows affected.
UPDATE assessments, assessment_types
SET assessments.assessment_type_id = assessment_types.id
WHERE (assessment_types.description = "Skills Assessment" AND assessments.id = 2);
Basically I have assessment_types with id and description column, and I just have the id in the assessments.assessment_type_id
I need to update the id.
I searched and couldn't find quite what I need for this.
Thanks!
Table Data:
assessment_types
id description
1 Knowledge Assessment
2 Skill Assessment
3 Personal Information
4 Natural Skills
Table Structure:
--
-- Table structure for table `assessments`
--
CREATE TABLE IF NOT EXISTS `assessments` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) COLLATE utf8_bin NOT NULL,
`acronym` varchar(255) COLLATE utf8_bin NOT NULL,
`assessment_type_id` int(11) NOT NULL,
`language_id` int(11) NOT NULL,
`date_created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`date_updated` date NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `id` (`id`),
KEY `assessment_type_id` (`assessment_type_id`),
KEY `language_id` (`language_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin AUTO_INCREMENT=2385 ;
--
-- Table structure for table `assessment_types`
--
CREATE TABLE IF NOT EXISTS `assessment_types` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`description` varchar(255) CHARACTER SET latin1 NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `id` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin AUTO_INCREMENT=7 ;
You can try doing an explicit join of the two tables in your UPDATE statement:
UPDATE assessments a
INNER JOIN assessment_types at
ON a.assessment_type_id = at.id
SET a.assessment_type_id = at.id
WHERE (at.description = "Skills Assessment" AND a.id = 2);
We have the following two tables:
CREATE TABLE IF NOT EXISTS `gp` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`amount` decimal(15,2) NOT NULL,
`user` varchar(100) NOT NULL DEFAULT '',
`status` tinyint(2) NOT NULL DEFAULT '1',
`ip` varchar(20) NOT NULL DEFAULT 'N/A',
`token` varchar(100) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1;
CREATE TABLE IF NOT EXISTS `gp_logs` (
`id` int(11) NOT NULL,
`log` varchar(1000) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
We JOIN them, for statistics, but we do this rarely, since the data from the 2nd table is not used too often except when we need to verify things.
Considering that we have many queries per second, how can our query be optimized to use 1 INSERT query instead of two and to insert the correct id in the 2nd table (gp_logs) that was generated by the INSERT into table gp?
Right now, we do a combination of MYSQL with PHP:
mysqli_query($con,"INSERT INTO `gp` (amount,user) VALUES ('1234','1')");
$id = mysqli_insert_id($con);
mysqli_query($con,"INSERT INTO gp_logs(id,log) VALUES ('$id','some_data')");
We want to eliminate the requirement of PHP for getting the last inserted ID and to insert both entries by running a single INSERT query (with a JOIN).
hope you are well.
I have a table in a MySQL (MariaDB) database with the below schema:
CREATE TABLE `scheduled_immobilise` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`account` varchar(32) COLLATE utf8_unicode_ci DEFAULT NULL,
`device` varchar(32) COLLATE utf8_unicode_ci DEFAULT NULL,
`allow_from` time DEFAULT NULL,
`allow_to` time DEFAULT NULL,
`active` varchar(6) COLLATE utf8_unicode_ci DEFAULT NULL,
`last_updated` timestamp NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
`cron_id_from` int(11) DEFAULT NULL,
`cron_id_to` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `unique` (`account`,`device`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
What I am trying to do is write a query that will either create a row (if the unique index doesn't exist), or if it already exists update it. I know you can do this by doing a select query first, but ultimately i was hoping to avoid this. Below is the SQL query I am using to create. Please note this is using PDO named placeholders..
INSERT INTO
scheduled_immobilise (
account,
device,
allow_from,
allow_to,
active
)
VALUES (
:account,
:device,
:allow_from,
:allow_to,
:active
)
Any help is much appreciated, thanks in advance!
Paul.
There's exactly a mysql option for this
INSERT INTO
scheduled_immobilise (
account,
device,
allow_from,
allow_to,
active
)
VALUES (
:account,
:device,
:allow_from,
:allow_to,
:active
)
ON DUPLICATE KEY UPDATE account = :account, device = device...etc
a slightly more correct answer
INSERT INTO
scheduled_immobilise (
account,
device,
allow_from,
allow_to,
active
)
VALUES (
:account,
:device,
:allow_from,
:allow_to,
:active
)
ON DUPLICATE KEY UPDATE
account = values(account),
device = values(device)
...etc
it will let you to use placeholders of any type, in any mode and with any driver beside PDO, while other answer will work only if emulation mode for PDO is turned on.
Here is database structure, generated with red bean php:
CREATE TABLE `attrib` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`type` tinyint(3) unsigned DEFAULT NULL,
`value` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=10 ;
CREATE TABLE `attrib_photo` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`attrib_id` int(11) unsigned DEFAULT NULL,
`photo_id` int(11) unsigned DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `UQ_e472845bf988796e2d3eceb91e2745b95f3aa534` (`attrib_id`,`photo_id`),
KEY `index_for_attrib_photo_attrib_id` (`attrib_id`),
KEY `index_for_attrib_photo_photo_id` (`photo_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=19 ;
CREATE TABLE `photo` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`filepath` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
`date` set('1') COLLATE utf8_unicode_ci DEFAULT NULL,
`iscolored` tinyint(3) unsigned DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=4 ;
ALTER TABLE `attrib_photo`
ADD CONSTRAINT `attrib_photo_ibfk_1` FOREIGN KEY (`attrib_id`) REFERENCES `attrib` (`id`) ON DELETE CASCADE,
ADD CONSTRAINT `attrib_photo_ibfk_2` FOREIGN KEY (`photo_id`) REFERENCES `photo` (`id`) ON DELETE CASCADE;
I'm making manually constructed query:
output of R::debug(); R::getAll($sql);
select filepath
from photo
inner join attrib as attrib4 on attrib4.type = 4 and attrib4.value in ("Dmitry")
inner join attrib_photo as attrib_photo4 on attrib_photo4.attrib_id = attrib4.id and attrib_photo4.photo_id = photo.id WHERE 1=1 LIMIT 0,25
Array ( )
resultset: 0 rows
[]
The result set is empty, but the base contains records, which fall under requirements, and running sql manually in phpMyAdmin shows them.
What's the problem with query, are there any additional debug info I can deal with to solve the problem? Thanks.
Update:
A little detail was missing, in original query I used unicode string for photo attribute search. After some investigations I found that php code works correctly and wrong encoding conversion happens on mysql side. Decision was to change collation of whole database to utf8_unicode_ci. Thanks for attention, and sorry for missing info in question.