Mysql UPDATING statement in datetime - mysql

i know its kind of weird but mind if somebody there look for this...
i have a 2 table which is
tableA
id | name | datetime -> format is int(11), varchar(128) datetime()
1 | 'foo bar' | '2014-08-04 00:53:16''
tableB
id | name | datetime | -> format is the same
1 | 'foo bar ' | null
using this statement
UPDATE tableA a
inner join tableB b on b.name = a.name
SET a.datetime = b.datetime
its say
Error Code: 1292. Truncated incorrect time value: '840:53:16';
what the... :)
if i select this using its own format
select * from tableA a inner join tableB b on b.name = a.name
its show
id | name | datetime |id | name | datetime |
1 | 'foo bar' | '2014-08-04 00:53:16'' | 1 | 'foo bar ' | null
am i doing something wrong??
if i use
show create table tableA
CREATE TEMPORARY TABLElist_of_in(
idint(11) NOT NULL,
namevarchar(128) NOT NULL,
datetimedatetime NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1
show create table tableB
CREATE TEMPORARY TABLElist_of_in(
idint(11) NOT NULL,
namevarchar(128) NOT NULL,
datetimedatetime NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1
by the way , im creating store procedure right now and its working in my localhost
but when i try it to the server, its not working and, after 6 hours i found out that this is the part that is not working...
by the way thanks for reading eheheh :))

I can't replicate your problem.
I recreated your tables, and when I run your query, it replaces tableA's datetime with the null from tableB. I'm guessing that you've built a simplified model of what is actually happening in your database? If that's the case, then the model you've made no longer highlights the problem.
What I did notice though, is that the error you are getting, is suggesting that the date format for one field doesn't match the other. I would check that both fields are in fact datetime, and that one isn't actually a varchar with the date in it.
Here's the dump of the sql to create my testing environment. If you run this (which will wipe TableA and TableB BTW), then run the query yourself, it should succeed.
# Dump of table tableA
# ------------------------------------------------------------
DROP TABLE IF EXISTS `tableA`;
CREATE TABLE `tableA` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(128) DEFAULT NULL,
`datetime` datetime DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
LOCK TABLES `tableA` WRITE;
/*!40000 ALTER TABLE `tableA` DISABLE KEYS */;
INSERT INTO `tableA` (`id`, `name`, `datetime`)
VALUES
(1,'foobar','2014-08-04 00:53:16');
/*!40000 ALTER TABLE `tableA` ENABLE KEYS */;
UNLOCK TABLES;
# Dump of table tableB
# ------------------------------------------------------------
DROP TABLE IF EXISTS `tableB`;
CREATE TABLE `tableB` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(128) DEFAULT NULL,
`datetime` datetime DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
LOCK TABLES `tableB` WRITE;
/*!40000 ALTER TABLE `tableB` DISABLE KEYS */;
INSERT INTO `tableB` (`id`, `name`, `datetime`)
VALUES
(1,'foobar',NULL);
/*!40000 ALTER TABLE `tableB` ENABLE KEYS */;
UNLOCK TABLES;

Related

Mysql Select query: Select employees that their position are both CEO and Owner

I have a below Table Diagram which consists mainly of 4 Tables, I would like to retrieve the company_name and person_name which is their position (CEO and Owner) of the same company.
Companies Table
People Table
Positions Table
Company_people table that combines the above three tables using foreign keys
Here are my Mysql Tables:
#
# Structure for table "companies"
#
DROP TABLE IF EXISTS `companies`;
CREATE TABLE `companies` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;
#
# Data for table "companies"
#
INSERT INTO `companies` VALUES (1,'Apple'),(2,'Microsoft'),(3,'Tesla'),(4,'SpaceX');
#
# Structure for table "company_person"
#
DROP TABLE IF EXISTS `company_person`;
CREATE TABLE `company_person` (
`cp_id` int(11) NOT NULL AUTO_INCREMENT,
`company_id` int(11) NOT NULL,
`person_id` int(11) NOT NULL,
`position_id` int(11) NOT NULL,
PRIMARY KEY (`cp_id`)
) ENGINE=InnoDB AUTO_INCREMENT=21 DEFAULT CHARSET=utf8;
#
# Data for table "company_person"
#
INSERT INTO `company_person` VALUES (1,1,13,1),(2,1,13,2),(3,2,12,2),(4,2,12,1),(5,4,11,2),(6,4,11,1),(7,3,11,1),(8,3,11,2),(9,1,14,3),(10,2,16,3),(11,3,17,4),(12,4,20,3),(13,4,17,3),(14,2,18,3),(15,3,18,2),(16,4,17,2),(17,4,17,4),(18,1,12,2),(19,3,12,2),(20,4,12,1);
#
# Structure for table "people"
#
DROP TABLE IF EXISTS `people`;
CREATE TABLE `people` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=21 DEFAULT CHARSET=utf8;
#
# Data for table "people"
#
INSERT INTO `people` VALUES (11,'Elon Mask'),(12,'Bill Gates'),(13,'Steve Jobs'),(14,'Azad Omer'),(15,'Johney Deep'),(16,'Brad Pitt'),(17,'Jeff'),(18,'Zukerberg'),(19,'Will Smith'),(20,'Rapar');
#
# Structure for table "position"
#
DROP TABLE IF EXISTS `position`;
CREATE TABLE `position` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;
#
# Data for table "position"
#
INSERT INTO `position` VALUES (1,'Owner'),(2,'CEO'),(3,'Stake Holder'),(4,'Third Party');
Now, I would like to retrive company_name, person_name that are thier position are (CEO and Owner) of the same company, here are what I've tried so far:
SELECT
com.name,
p.name,
COUNT(*)
FROM `company_person`
INNER JOIN companies com
ON com.id=company_id
INNER JOIN people p
ON p.id = person_id
WHERE position_id IN(1, 2) # 1=Owner, 2=CEO
GROUP BY company_id, person_id
HAVING COUNT(*) > 1;
Which Gives me a result which I belive is not accurate this query:
| com | person | COUNT(*)
| --- | ------ | --------
| Apple | Steve Jobs | 2
| Microsoft | Bill Gates | 2
| Tesla | Elon Mask | 2
| SpaceX | Elon Mask | 2
My question is, is this way the proper way?
Can you please help me out if you know another proper way which is correct and better than my way?
From what I understand that you are wanting, there are a number of issues
Your primary table has multiple entries for the same company_id and person_id, so you have to do a distinct.
Count makes no sense at all, so I have dropped it.
IN will do an OR function, you want an AND. I have done two sub-queries for this aliasing the company_person to a different name to avoid confusion.
So here is one simple solution to illustrate the concept.
select distinct p1.person_id, p1.company_id, com.name company, p.name person
from company_person p1
inner join companies com
on com.id=p1.company_id
inner join people p
on p.id = p1.person_id
where p1.position_id = 1
and exists (select p2.position_id
from company_person p2
where p2.position_id = 2)
I have left the ids in there as it helps to build up the query before you do the joins to fetch the names. You can remove them from the select.

MySQL create table and trigger

Can anyone help me understand what this code does?
CREATE TABLE `exams` (
`id` int(11) NOT NULL, `score` int(2) NOT NULL, `class` int(11) NOT NULL, `date` date NOT NULL, PRIMARY KEY (`class`,`date`,`id`));
CREATE TRIGGER `trig3` BEFORE INSERT ON `exams` FOR EACH ROW SET #xxx = #xxx + 1;
SET #xxx = 0;
INSERT INTO `exams` VALUES (10001,24,1,'2013-09-16'), (10005,30,1,'2013-09-16'), (10083,30,1,'2014-03-21'), (10120,26,1,'2014-03-21'), (10035,23,1,'2014-07-22'), (10005,28,2,'2014-01-23'), (10001,27,2,'2014-06-30'), (10001,25,4,'2014-01-23'), (10083,22,4,'2014-01-23'), (10120,30,4,'2014-01-23'), (10005,22,4,'2014-03-21');
SELECT #xxx;
I understand the creation of the table and the insertion of values but i don't get the rest of it.
The code seams to be a workaround way to count or check if the multi insert inserted all records or not.
SELECT #xxx;
| #xxx |
| ---- |
| 11 |
But MySQL doesn't have a native way to find that out.
see demo
A more easy MySQL code to do the same without needing the TRIGGER code and SET.
But it will require a new table structure to function.
CREATE TABLE `esami` (
`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY
, `id_studente` int(11) NOT NULL
, `voto` int(2) NOT NULL
, `id_corso` int(11) NOT NULL
, `data` date NOT NULL
, UNIQUE KEY (`id_corso`,`data`,`id_studente`)
);
And the query to test if all records where inserted by the multi insert.
SELECT
COUNT(*)
FROM
esami
WHERE
id BETWEEN LAST_INSERT_ID() AND LAST_INSERT_ID() + 11;
see demo

How to concat_ws primarykey(id) and date in a new column on same table?(MySQL)

I need add a new column named date_id by using concat_ws('-', curdate,id) on a same table, the id is a primarykey and auto_increment.
How to do this?
I tried add a column and updated it. it worked, but when I insert some new row, the error showed Filed 'id' doesnot have a default value.
How to solve this?
ALTER TABLE table1 ADD date_id VARCHAR(50);
UPDATE table1 SET date_id = CONCAT_WS('-',date_format(CURDATE(),'%Y%m%d'),id);
update question
I have created a table:
USE table_name;
CREATE TABLE IF NOT EXISTS `gzsrieQA`(
`id` INT(3) UNSIGNED ZEROFILL AUTO_INCREMENT,
`record_id` VARCHAR(50),
`date` date,
`pro_name` VARCHAR(50),
`error_info` VARCHAR(255),
`error_describe` VARCHAR(255),
`reason` VARCHAR(255),
`solution` VARCHAR(255),
`solution_file` BLOB,
`solution_file_name` VARCHAR(50),
PRIMARY KEY ( `id` )
)ENGINE=InnoDB DEFAULT CHARSET=utf8;
ALTER table_name AUTO_INCREMENT = 001;
UPDATE table_name SET record_id = CONCAT_WS('-','SRIE-DSJ-QA',date_format(CURDATE(),'%Y%m%d'),id);
When I insert into some new data, the result showed 'record_id' is null. it means I need a trigger? But the question is if I insert lots of data, the trigger is too slow.Is there any solution to solve this if I don't use trigger?
For example:
|id|record_id|name|
|-----|-----|-----|
|001| |ABC|
|002| |xyz|
# I want to get:
|id|record_id|name|
|-----|-----|-----|
|001|ABC001|ABC|
|002|xyz002|xyz|
# and when I insert into name=AAA, the result is:
|id|record_id|name|
|-----|-----|-----|
|001|ABC001|ABC|
|002|xyz002|xyz|
|003|aaa003|AAA|
THANKS!
I tried MySQL and it allowed your statement however you can set a default and then remove it.
select version();
| version() |
| :-------- |
| 8.0.13 |
create table table1 (id int auto_increment primary key);
✓
insert into table1(id) values (NULL),(NULL),(NULL),(NULL)
✓
ALTER TABLE table1 ADD date_id VARCHAR(50) default '';
✓
UPDATE table1 SET date_id = CONCAT_WS('-',date_format(CURDATE(),'%Y%m%d'),id);
✓
select * from table1
id | date_id
-: | :---------
1 | 20190111-1
2 | 20190111-2
3 | 20190111-3
4 | 20190111-4
show create table table1
Table | Create Table
:----- | :-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
table1 | CREATE TABLE `table1` (<br> `id` int(11) NOT NULL AUTO_INCREMENT,<br> `date_id` varchar(50) DEFAULT '',<br> PRIMARY KEY (`id`)<br>) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
alter table table1 alter column date_id DROP DEFAULT, ALGORITHM=INPLACE, LOCK=NONE;
✓
show create table table1;
Table | Create Table
:----- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
table1 | CREATE TABLE `table1` (<br> `id` int(11) NOT NULL AUTO_INCREMENT,<br> `date_id` varchar(50),<br> PRIMARY KEY (`id`)<br>) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
db<>fiddle here

How to copy a very large table into another table in MYSQL?

I have a large table with 110M rows. I would like to copy some of the fields into a new table and here is a rough idea of how I am trying to do:
DECLARE l_seenChangesTo DATETIME DEFAULT '1970-01-01 01:01:01';
DECLARE l_migrationStartTime DATETIME;
SELECT NOW() into l_migrationStartTime;
-- See if we've run this migration before and if so, pick up from where we left off...
IF EXISTS(SELECT seenChangesTo FROM migration_status WHERE client_user = CONCAT('this-migration-script-', user())) THEN
SELECT seenChangesTo FROM migration_status WHERE client_user = CONCAT('this-migration-script-', user()) INTO l_seenChangesTo;
SELECT NOW() as LogTime, CONCAT('Picking up from where we left off: ', l_seenChangesTo) as MigrationStatus;
END IF;
INSERT IGNORE INTO newTable
(field1, field2, lastModified)
SELECT o.column1 AS field1,
o.column2 AS field2,
o.lastModified
FROM oldTable o
WHERE
o.lastModified >= l_seenChangesTo AND
o.lastModified <= l_migrationStartTime;
INSERT INTO migration_status (client_user,seenChangesTo)
VALUES (CONCAT('this-migration-script-', user()), l_migrationStartTime)
ON DUPLICATE KEY UPDATE seenChangesTo=l_migrationStartTime;
Context:
CREATE TABLE IF NOT EXISTS `newTable` (
`field1` varchar(255) NOT NULL,
`field2` tinyint unsigned NOT NULL,
`lastModified` datetime NOT NULL,
PRIMARY KEY (`field1`, `field2`),
KEY `ix_field1` (`field1`),
KEY `ix_lastModified` (`lastModified`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `oldTable` (
`column1` varchar(255) NOT NULL,
`column2` tinyint unsigned NOT NULL,
`lastModified` datetime NOT NULL,
PRIMARY KEY (`column1`, `column2`),
KEY `ix_column1` (`column1`),
KEY `ix_lastModified` (`lastModified`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `migration_status` (
`client_user` char(64) NOT NULL,
`seenChangesTo` char(128) NOT NULL,
PRIMARY KEY (`client_user`)
);
Note: I have a few more columns in oldTable. Both oldTable and newTable are in same DB schema using mysql.
What's the general strategy when copying a very table? Should I perform this migration in an iterative manner by copy say 50,000 rows at time.
The insert speed doing a migration like this iteratively is going to be dreadfully slow. Why not SELECT oldTable INTO OUTFILE, then LOAD DATA INFILE ?

MySQL error #1690 (BIGINT UNSIGNED value is out of range) for UNIX_TIMESTAMP()

i get error #1690 - BIGINT UNSIGNED value is out of range for this query:
SELECT * FROM `user`
WHERE ROUND( ( UNIX_TIMESTAMP() - `expire` ) / 86400 ) = 7
i read about this error in Stackoverflow and see some notes about cast but i can't apply them to this query.
Your second value in table will give negative result, so you get an error.
To make negative results possible in your case, use before query
SET sql_mode = 'NO_UNSIGNED_SUBTRACTION';
Schema
CREATE TABLE IF NOT EXISTS `user` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`expire` int(10) unsigned NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=3 ;
--
-- Dumping data for table `test`
--
truncate table user;
INSERT INTO `user` (`id`, `expire`) VALUES
(1, 1234567890),
(2, 1923456780),
(3, 1449397282),
(4,1449397282+3600); -- note this is based on this moment I am writing this about a day ahead
Query
select id,expire,seconds from
( select id,expire,TIME_TO_SEC(TIMEDIFF(from_unixtime(expire), now())) as seconds
from user
) xDerived
where seconds>0 and seconds<604800; -- # of seconds in a week
+----+------------+---------+
| id | expire | seconds |
+----+------------+---------+
| 4 | 1449400882 | 2870 |
+----+------------+---------+
So things that have not expired yet, but will within 1 week