how to get average time 'xx:xx:xx' on mysql? - mysql

please see the the test data bellow. I want to get the avgtime (=timeonsite/visits) and display as "xx:xx:xx" result in mysql. how can I get it?
SET FOREIGN_KEY_CHECKS=0;
-- ----------------------------
-- Table structure for `t`
-- ----------------------------
DROP TABLE IF EXISTS `t`;
CREATE TABLE `t` (
`id` int(11) NOT NULL auto_increment,
`timeOnsite` time default NULL,
`visits` int(11) default NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of t
-- ----------------------------
INSERT INTO `t` VALUES ('1', '04:05:30', '20');
INSERT INTO `t` VALUES ('2', '03:00:00', '10');
INSERT INTO `t` VALUES ('3', '00:01:30', '17');

You can use TIME_TO_SEC function to change xx:xx:xx format to seconds.
SELECT TIME_TO_SEC('00:01:30') / 17; # return 5.2941
And then through SEC_TO_TIME you can convert seconds to time back as below :
SELECT SEC_TO_TIME(TIME_TO_SEC('00:01:30') / 17); # return 00:00:05

Are sure that you calculate avgtime in such way?
If yes, mysql select below:
select id, timeOnsite,visits, SEC_TO_TIME(TIME_TO_SEC(timeOnsite)/visits) as avgtime
from t

Related

Can I run a SELECT query that depends on two rows from a table without using subqueries

Suppose the schemas are
users(id, name)
users_attributes(user_id, attribute_name, attribute_value)
Sample data:
--
-- Database: `sample_db`
--
CREATE DATABASE IF NOT EXISTS `sample_db` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
USE `sample_db`;
-- --------------------------------------------------------
--
-- Table structure for table `users`
--
CREATE TABLE `users` (
`id` int(11) NOT NULL,
`name` varchar(50) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
--
-- Dumping data for table `users`
--
INSERT INTO `users` (`id`, `name`) VALUES
(1, 'Tim'),
(2, 'Joe'),
(3, 'Bob');
-- --------------------------------------------------------
--
-- Table structure for table `users_attributes`
--
CREATE TABLE `users_attributes` (
`user_id` int(11) NOT NULL,
`attribute_name` varchar(50) NOT NULL,
`attribute_value` varchar(50) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
--
-- Dumping data for table `users_attributes`
--
INSERT INTO `users_attributes` (`user_id`, `attribute_name`, `attribute_value`) VALUES
(1, 'height', '10'),
(1, 'over_18', 'yes'),
(2, 'height', '5'),
(3, 'height', '7');
--
-- Indexes for dumped tables
--
--
-- Indexes for table `users`
--
ALTER TABLE `users`
ADD PRIMARY KEY (`id`);
--
-- Indexes for table `users_attributes`
--
ALTER TABLE `users_attributes`
ADD UNIQUE KEY `user_id` (`user_id`,`attribute_name`,`attribute_value`);
--
-- AUTO_INCREMENT for dumped tables
--
--
-- AUTO_INCREMENT for table `users`
--
ALTER TABLE `users`
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=4;
COMMIT;
Right now I'm calling INNER JOIN on a specific attribute_name so my selection also returns that along with the user id and name. Now I want to exclude from whatever I selected, if they contain a certain other attribute. I know I can accomplish that by using a NOT IN (SELECT ...) conditional but can I do that without having to select again?
EDIT:
Attributes may or may not exist for all users. For example, I would like to fetch id, name, attribute_value where attribute_name = height but only if attribute_name over_18 does not exist or is 'no'

SQL insert query so slow

Each 10,000 rows take about 124 second to insert ,how this can be faster
This is the table i insert to
CREATE TABLE `orders`
(`oid` int(11) NOT NULL AUTO_INCREMENT,
`countryCode` varchar(10) NOT NULL,
`date` datetime NOT NULL,
`id` bigint(20) NOT NULL,
`productId` bigint(20) NOT NULL,
PRIMARY KEY (`oid`),
UNIQUE KEY `id` (`id`),
KEY `date` (`date`),
KEY `productId` (`productId`)
) ENGINE=InnoDB AUTO_INCREMENT=4833010 DEFAULT CHARSET=latin1
this is the query i used
ALTER TABLE `orders` DISABLE KEYS;
SET FOREIGN_KEY_CHECKS=0;
INSERT IGNORE INTO `orders` (`countryCode`, `date`, `id`,`productId`)
VALUES
('ru','2019-04-09 06:59',100453324298986,32829863707) ,
('fr','2019-04-09 05:59',100645420835625,32829863707) ,
('ru','2019-04-08 12:04',704482263524094,32829863707)
.......etc 10,000 rows here at once
Try to write insert statement as
START TRANSACTION;
INSERT INTO `insert_table` (`datetime`, `uid`, `content`, `type`) VALUES ('0', 'userid_0', 'content_0', 0);
INSERT INTO `insert_table` (`datetime`, `uid`, `content`, `type`) VALUES ('1', 'userid_1', 'content_1', 1);
...
COMMIT;
I think it's slow because you trying to INSERT bulk records at once.
You have several methods to speedup the process.
1) Insert records batch wise. ( 500-1000 records at a time )
2) Increase Memory parameters in MYSQL. so the memory will be increased.
(http://www.geeksengine.com/database/data-manipulation/bulk-insert.php)
Try This for batch Update
SET autocommit=0;
SET unique_checks=0;
SET foreign_key_checks=0;
SET GLOBAL bulk_insert_buffer_size =1024*1024*512;
START TRANSACTION;
INSERT IGNORE INTO `orders` (`countryCode`, `date`, `id`,`productId`)
VALUES
('ru','2019-04-09 06:59',100453324298986,32829863707) ,
('fr','2019-04-09 05:59',100645420835625,32829863707) ,
('ru','2019-04-08 12:04',704482263524094,32829863707)
.......etc 600 rows here at once
COMMIT;
START TRANSACTION;
INSERT IGNORE INTO `orders` (`countryCode`, `date`, `id`,`productId`)
VALUES
('ru','2019-04-09 06:59',100453324298986,32829863707) ,
('fr','2019-04-09 05:59',100645420835625,32829863707) ,
('ru','2019-04-08 12:04',704482263524094,32829863707)
.......etc 600 rows here at once
COMMIT;
Note:
1) If this is slow Try changing bulk_insert_buffer_size and no of rows per insert.
2) Check your PC Free Memory/CPU before executing the query . try to free it as much as possible

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

how to get records count of this month?

how to get records count of this month?
I want to count user of this month ? "this month" should be calculate by mysql itself. how to write the sql?
SET FOREIGN_KEY_CHECKS=0;
-- ----------------------------
-- Table structure for `a`
-- ----------------------------
DROP TABLE IF EXISTS `a`;
CREATE TABLE `a` (
`id` int(11) NOT NULL auto_increment,
`name` varchar(30) default NULL,
`date` datetime default NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=8 DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of a
-- ----------------------------
INSERT INTO `a` VALUES ('1', 'jimy', '2014-02-11 09:24:42');
INSERT INTO `a` VALUES ('7', 'khon', '2014-02-19 09:24:50');
INSERT INTO `a` VALUES ('3', 'tina', '2014-01-11 09:25:03');
INSERT INTO `a` VALUES ('4', 'kelvin', '2013-12-11 09:25:09');
INSERT INTO `a` VALUES ('5', 'ricky', '2014-02-12 09:25:14');
you can try this
Select count(*)
FROM a
WHERE MONTH(date) = MONTH(NOW())
GROUP BY MONTH(date)
MONTH(date) only returns the month number, it won't work with multiple years data.
SELECT COUNT(*) count
FROM a
WHERE EXTRACT(YEAR_MONTH FROM a.date) = EXTRACT(YEAR_MONTH FROM NOW())
Or you could use:
SELECT COUNT(*) count
FROM a
WHERE DATE_FORMAT(a.date,'%Y%m') = DATE_FORMAT(NOW(),'%Y%m')

how can i count how many people in table a?

how can i count how many people in table a?
there 4 people exists in the below table , how can i get "4" in mysql?
SET FOREIGN_KEY_CHECKS=0;
-- ----------------------------
-- Table structure for `a`
-- ----------------------------
DROP TABLE IF EXISTS `a`;
CREATE TABLE `a` (
`products_id` int(11) NOT NULL auto_increment,
`name` varchar(30) default NULL,
`date` datetime default NULL,
PRIMARY KEY (`products_id`)
) ENGINE=MyISAM AUTO_INCREMENT=8 DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of a
-- ----------------------------
INSERT INTO `a` VALUES ('1', 'jimmy', '2014-02-11 09:24:42');
INSERT INTO `a` VALUES ('7', 'khon', '2014-02-19 09:24:50');
INSERT INTO `a` VALUES ('3', 'jimmy', '2014-01-11 09:25:03');
INSERT INTO `a` VALUES ('4', 'kelvin', '2013-12-11 09:25:09');
INSERT INTO `a` VALUES ('5', 'ricky', '2014-02-12 09:25:14');
Use count on distinct name of the persons.
select count(distinct name) from a mytable
select count(distinct(name)) as count from a;
You can use COUNT LIke
SELECT COUNT(DISTINCT name) FROM a;
You are unclear in your question. What is it that you want to count?, number of distinct persons or the total number of people in the table?
SELECT COUNT(name) from a;
You may use DISTINCT clause with it or you can also perform GROUP BY to get the count of users by grouping them.