Covert Convert BigInt timestamp to a real Date - mysql

I have an old database however i cant remeber the script i used but need to convert a date if anyone can help
(287,1090231200,1090233000,'Diary',0,0,0,1,0)
This the the layout
`id` int(11) NOT NULL auto_increment,
`start_time` bigint(20) default NULL,
`end_time` bigint(20) default NULL,
`description` blob,
`is_note` tinyint(4) default '0',
`private` tinyint(4) default '0',
`rec_app_id` int(11) NOT NULL default '0',
`status` tinyint(4) default '0',
`all_day` tinyint(4) default '0',
PRIMARY KEY (`id`),
UNIQUE KEY `ID_2` (`id`),
KEY `ID` (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=15212 DEFAULT CHARSET=latin1 PACK_KEYS=1;

Try this (for example if your result is in miliseconds - divide by 1000 to get result in seconds):
SELECT FROM_UNIXTIME(600000000/1000);
See the syntax for more details.
Note: If you use UNIX_TIMESTAMP() and FROM_UNIXTIME() to convert between TIMESTAMP values and Unix timestamp values, the conversion is lossy because the mapping is not one-to-one in both directions.
EDIT: Also read this and this question.

Related

Mysql slow query on large table

With Mysql 5.6.10, I have a table like this:
CREATE TABLE `es_user_action` (
`id` bigint(11) unsigned NOT NULL AUTO_INCREMENT,
`user_id` bigint(11) unsigned NOT NULL,
`company_id` bigint(11) unsigned NOT NULL,
`work_id` bigint(11) unsigned NOT NULL,
`action` tinyint(2) NOT NULL COMMENT '10, 20, 30, 40',
`action_id` bigint(11) unsigned DEFAULT NULL,
`apply_id` bigint(11) unsigned DEFAULT '0',
`apply_display_id` varchar(100) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`action_time` datetime NOT NULL,
`scout_time` datetime NOT NULL,
`register_datetime_sorting` datetime DEFAULT NULL,
`score` tinyint(2) DEFAULT '0',
`is_pending` tinyint(2) DEFAULT '0',
`apply_status` tinyint(2) DEFAULT '2' COMMENT '1: paid, 2: free',
`has_response` tinyint(2) DEFAULT '0',
`response_time` datetime DEFAULT NULL,
`is_shown` tinyint(2) DEFAULT '1',
`source` varchar(15) COLLATE utf8mb4_unicode_ci NOT NULL,
`created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `user_company_work` (`user_id`,`work_id`,`company_id`,`apply_id`,`source`),
KEY `IDX_2` (`company_id`,`is_shown`,`apply_status`,`apply_id`,`work_id`,`action_time`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=436896779 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
The full query I want to perform on the table would be the following:
SELECT
`id` AS `seqNo`,
`company_id` AS `companyId`,
`work_id` AS `workId`,
`action` AS `userActionType`,
`action_time` AS `userActionDatetime`,
`is_pending`,
`apply_status`,
`action_id`,
`source`,
`user_id` AS `userId`,
`apply_display_id`
FROM
`es_user_action`
WHERE
`company_id` = 449664
AND `is_shown` = 1
AND `apply_status` = 1
AND `apply_id` = 0
AND `action_time` >= '2021-01-05 15:56:14'
ORDER BY
is_pending ASC,
action ASC,
score DESC,
CASE
source
WHEN "entenshoku" THEN
action_time
END DESC,
CASE
WHEN source <> "entenshoku" THEN
action_time
END ASC
LIMIT 100 OFFSET 0;
The table has around 15 million rows and the following query takes around 15 seconds. The query becomes very slow.
Can anyone help out? Thanks in advance.
UPDATED:
This is the explain query result:
KEY `IDX_2` (`company_id`,`is_shown`,`apply_status`,`apply_id`,`work_id`,`action_time`)
Work_id is in the way of that index being effective for that SELECT. Remove it. That should speed up the query some. Still the are too many columns and expressions involved in the WHER and ORDER BY to do much more to help.
Changing BIGINTs to smaller INT types will help some (by shrinking the table).
I'm pretty sure that what you have cannot work.
You have is a dynamically changing ORDER BY, depending on the value of source. But which row's source?
If you could decide before issuing the query whether to scan action_time ascending or descending, which value of source would you pick?
Delete this Question, rewrite the query, then open another Question if you still have an issue.

missing default value for NOT NULL TIMESTAMP?

I want to execute the following mysql statement from the framadate software.
CREATE TABLE IF NOT EXISTS `sondage` (
`id_sondage` char(16) NOT NULL,
`commentaires` text,
`mail_admin` varchar(128) DEFAULT NULL,
`nom_admin` varchar(64) DEFAULT NULL,
`titre` text,
`id_sondage_admin` char(24) DEFAULT NULL,
`date_creation` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`date_fin` timestamp NOT NULL,
`format` varchar(2) DEFAULT NULL,
`mailsonde` tinyint(1) DEFAULT '0',
`statut` int(11) NOT NULL DEFAULT '1' COMMENT '1 = actif ; 0 = inactif ; ',
UNIQUE KEY `id_sondage` (`id_sondage`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
But I get the error: Error in query (1067): Invalid default value for 'date_fin'
I wonder what that means, because there is no default value given for date_fin.
It sounds to me like your MySQL server is insisting you provide a default value for your date_fin column. Try this.
...
`date_fin` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
...
In general, it's a reasonably good practice to provide default values for NOT NULL columns.

mysql speed up update statement for copying values between tables

I have 2 tables where I am trying to copy values from migrate table to regular table. It seems to take awhile. (10 minutes for 43k records)
UPDATE phppos_sales_items,phppos_sales_items_migrate
SET
phppos_sales_items.subtotal = phppos_sales_items_migrate.subtotal,
phppos_sales_items.tax = phppos_sales_items_migrate.tax,
phppos_sales_items.total = phppos_sales_items_migrate.total,
phppos_sales_items.profit = phppos_sales_items_migrate.profit
WHERE
phppos_sales_items.sale_id = phppos_sales_items_migrate.sale_id and
phppos_sales_items.line = phppos_sales_items_migrate.line and
phppos_sales_items.item_id = phppos_sales_items_migrate.item_id;
Migrate Table
CREATE TABLE `phppos_sales_items_migrate` (
`sale_id` int(10) NOT NULL DEFAULT '0',
`item_id` int(10) NOT NULL DEFAULT '0',
`line` int(11) NOT NULL DEFAULT '0',
`subtotal` decimal(23,10) DEFAULT NULL,
`total` decimal(23,10) DEFAULT NULL,
`tax` decimal(23,10) DEFAULT NULL,
`profit` decimal(23,10) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
sales_items
CREATE TABLE `phppos_sales_items` (
`sale_id` int(10) NOT NULL DEFAULT '0',
`item_id` int(10) NOT NULL DEFAULT '0',
`rule_id` int(10) DEFAULT NULL,
`rule_discount` decimal(23,10) DEFAULT NULL,
`description` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
`serialnumber` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
`line` int(11) NOT NULL DEFAULT '0',
`quantity_purchased` decimal(23,10) NOT NULL DEFAULT '0.0000000000',
`item_cost_price` decimal(23,10) NOT NULL,
`item_unit_price` decimal(23,10) NOT NULL,
`regular_item_unit_price_at_time_of_sale` decimal(23,10) DEFAULT NULL,
`discount_percent` decimal(15,3) NOT NULL DEFAULT '0.000',
`commission` decimal(23,10) NOT NULL DEFAULT '0.0000000000',
`subtotal` decimal(23,10) NOT NULL DEFAULT '0.0000000000',
`tax` decimal(23,10) NOT NULL DEFAULT '0.0000000000',
`total` decimal(23,10) NOT NULL DEFAULT '0.0000000000',
`profit` decimal(23,10) NOT NULL DEFAULT '0.0000000000',
PRIMARY KEY (`sale_id`,`item_id`,`line`),
KEY `item_id` (`item_id`),
KEY `phppos_sales_items_ibfk_3` (`rule_id`),
CONSTRAINT `phppos_sales_items_ibfk_1` FOREIGN KEY (`item_id`) REFERENCES `phppos_items` (`item_id`),
CONSTRAINT `phppos_sales_items_ibfk_2` FOREIGN KEY (`sale_id`) REFERENCES `phppos_sales` (`sale_id`),
CONSTRAINT `phppos_sales_items_ibfk_3` FOREIGN KEY (`rule_id`) REFERENCES `phppos_price_rules` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
Is there any way to speed this up?
decimal(23,10) is excessive, especially for integral values, such as quantity_purchased. Shrinking the datatypes will help speed some.
Use a "multi-table Update" with JOIN ... ON ... syntax.
Let's see the output from
EXPLAIN
SELECT * FROM phppos_sales_items AS i
JOIN phppos_sales_items_migrate AS m
ON i.sale_id = m.sale_id
and i.line = m.line
and i.item_id = m.item_id;
If you have a new enough version of MySQL, also provide EXPLAIN UPDATE ...
Any chance there are new rows in migrate? If so, won't you need INSERT ... ON DUPLICATE KEY UPDATE ...?
43K rows in which table? How many in the other table?
In my opinion, adding Index to the Target Table are worth to try.
Since two tables are comparing the three columns for merging it, you might better to adding index to the phppos_sales_items_migrate table for (sale_id,item_id,line) columns.
Good Luck
PS. FYI, adding indexes to the table also take costs for updating and inserting thus minimize to the comparing columns.

Incorrect table definition; there can be only one TIMESTAMP column with CURRENT_TIMESTAMP in DEFAULT or ON UPDATE clause

I always get the error:
Incorrect table definition; there can be only one TIMESTAMP column with CURRENT_TIMESTAMP in DEFAULT or ON UPDATE clause
DROP TABLE IF EXISTS `characters`;
CREATE TABLE `characters`(
`id` int(11) NOT NULL AUTO_INCREMENT,
`accId` int(11) NOT NULL,
`charId` int(11) NOT NULL,
`charType` int(11) NOT NULL,
`level` int(11) NOT NULL,
`exp` int(11) NOT NULL,
`fame` int(11) NOT NULL,
`items` varchar(128) NOT NULL,
`hp` int(11) NOT NULL,
`mp` int(11) NOT NULL,
`stats` varchar(64) NOT NULL DEFAULT '"1,2,3,4,5,6,7,8"',
`dead` tinyint(1) NOT NULL DEFAULT '0',
`tex1` int(11) NOT NULL DEFAULT '0',
`tex2` int(11) NOT NULL DEFAULT '0',
`pet` int(11) NOT NULL DEFAULT '0',
`fameStats` varchar(128) NOT NULL DEFAULT 'eNoVytkRgCAMRdGH4IIbgmsPdmNVNmZf5n7kzM0kksLjJN2V4b30vcHK1YYam9hCxxqh5zpQI0wwQ4IFMhRYYeNjpw444YIfA3kDIA',
`createTime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`deathTime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`totalFame` int(11) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=14 DEFAULT CHARSET=utf8;
This is my first time using MySQL stuff. The reason I am using it because I downloaded a source for a game with server and this is needed.
The problem is isolated to these two lines
`createTime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`deathTime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
To get rid of the error, you need to modify one of those lines to remove the DEFAULT CURRENT_TIMESTAMP. MySQL only allows one timestamp column to be defined that way. For example:
`createTime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`deathTime` timestamp NOT NULL,
Because the deathTime column is defined as NOT NULL and doesn't have a default, you'll need to supply a value for deathTime whenever you insert a row. You could get the current date and time assigned to that column for an INSERT using a BEFORE INSERT trigger.
You are trying to, well, define more than "one TIMESTAMP column with CURRENT_TIMESTAMP in DEFAULT or ON UPDATE clause". Specifically, createTime and deathTime.
You Can't Do That.™

Find row that have a duplicate field, the filed type is blob

I have a table with many many duplicated row, I cannot create a unique value for the blob field, because is too large.
How can I find and delete the duplicate rows where the blob field (answer) is duplicated?
This is the table structure :
CREATE TABLE `answers` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`id_question` int(11) NOT NULL,
`id_user` int(11) NOT NULL,
`answer` blob NOT NULL,
`language` varchar(2) NOT NULL,
`datetime` datetime NOT NULL,
`enabled` int(11) NOT NULL DEFAULT '0',
`deleted` int(11) NOT NULL DEFAULT '0',
`spam` int(11) NOT NULL DEFAULT '0',
`correct` int(11) NOT NULL DEFAULT '0',
`notification_send` int(11) NOT NULL DEFAULT '0',
`correct_notification` int(11) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
KEY `id_question` (`id_question`),
KEY `id_user` (`id_user`),
KEY `enabled` (`enabled`)
) ENGINE=InnoDB AUTO_INCREMENT=1488 DEFAULT CHARSET=utf8mb4
probable you can use prefix of the column by substr() or left() and compare. How much size you want to take that depends on your data distribution or prefix uniqueness of the column data.
for uniqueness check you can fire the below query if the
select count(distinct left(answer, 128))/count(*), count(distinct left(answer, 256))/count(*) from answers.
This will provide you selectivity or data distribution in your column. suppose 128 gives you answer as 1 i.e. all unique if you take first 128 bytes then choose that amount of data from each row and work. Hope it helps.