How to calculate age in query? - mysql

How to calculate the age of the user inside a SQL query. Be aware I splitted the database into the fields: birthday, birthmonth and birthyear.
I created a fiddle to show what I mean.
CREATE TABLE IF NOT EXISTS `user_profile` (
`user_id` int(11) NOT NULL AUTO_INCREMENT,
`user_birthday` tinyint(4) NOT NULL,
`user_birthmonth` tinyint(4) NOT NULL,
`user_birthyear` smallint(6) NOT NULL,
PRIMARY KEY (`user_id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
INSERT INTO `user_profile`
(user_birthday, user_birthmonth, user_birthyear) VALUES (31, 12, 1990)

SqlFiddleDemo
SELECT YEAR(NOW()) - YEAR(birthday) - (DATE_FORMAT(birthday, '%m%d') < DATE_FORMAT(NOW(), '%m%d')) AS Age
FROM (
SELECT
CAST(CONCAT(`user_birthyear`, '-', `user_birthmonth`, '-', `user_birthday`) AS DATE) AS birthday
FROM user_profile ) AS s

Year(getdate()) - birthyear shall be enough

Related

How can I group_concat this mysql fields

I have this MySQL Query:
SELECT a.orcidid
, GROUP_CONCAT(distinct a.`from` SEPARATOR '<>' ) as StartDate
, GROUP_CONCAT(distinct a.`to` SEPARATOR '<>' ) as EndDate
from orcidaffils a
GROUP BY a.orcidid ;
For this DATA Table:
CREATE TABLE `orcidaffils` (
`recid` int(11) NOT NULL AUTO_INCREMENT,
`affil` varchar(6000) DEFAULT NULL,
`orcidid` varchar(100) DEFAULT NULL,
`city` varchar(100) DEFAULT NULL,
`country` varchar(100) DEFAULT NULL,
`from` date DEFAULT NULL,
`to` date DEFAULT NULL,
PRIMARY KEY (`recid`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of orcidaffils
-- ----------------------------
INSERT INTO `orcidaffils` VALUES ('2', 'Graz University of Technology', '0000-0004-1034-5187', 'Graz', 'AT', '2010-01-01', null);
INSERT INTO `orcidaffils` VALUES ('3', 'Ecole Polytechnique', '0000-0004-1034-5187','Palaiseau', 'FR', '2008-09-01', '2010-07-01');
INSERT INTO `orcidaffils` VALUES ('4', 'University of Würzburg', '0000-0004-1034-5187', 'Wurzburg', 'DE', '2005-09-01', '2007-12-01');
No I would like to get this output:
The question is how to group_concat that the beginndate and the enddate is merged together per affliliation.
2010-01-01-now<>2008-01-09 to 2010-01-07<>2005-01-09 to 2007-01-12
thanks for any usefull advice.
As per the image you've mentioned
you could try something like this:
SELECT a.orcidid ,
GROUP_CONCAT(a.`affil` SEPARATOR '<>' )
, GROUP_CONCAT(CONCAT(a.`from`, ' to ', IFNULL(a.`to`,'now')) SEPARATOR '<>' ) AS StartDate
FROM orcidaffils a
GROUP BY a.orcidid ;

Convert HOUR format into Day-Hour-Minute-Second in mysql

I am using this code am getting output in hours
with the below code.
Import script
CREATE TABLE `customerevent` ( `id` int NOT NULL, `Createddate` datetime DEFAULT NULL, `Modifiedate` datetime DEFAULT NULL, PRIMARY KEY (`id`) );
INSERT INTO customerevent (id, Createddate, Modifiedate) VALUES ('3', '2020-01-08 12:00:00', '2020-01-10 11:30:00');
CREATE TABLE holidays (
Id int NOT NULL AUTO_INCREMENT,
Holiday datetime DEFAULT NULL,
Account_of varchar(45) DEFAULT NULL,
PRIMARY KEY (Id));
My code :
SELECT d.Id, d.Createddate, d.Modifiedate,
SUM((TIMESTAMPDIFF(day, start_date, end_date) -
COALESCE((SELECT COUNT(*) FROM holidays WHERE holiday BETWEEN Createddate AND Modifiedate), 0))* 8 +
TIMESTAMPDIFF(minute, TIME(start_time), TIME(end_time)) / 60) task_time
FROM customerevent d
JOIN ( SELECT Id, DATE(Createddate) start_date, DATE(Modifiedate) end_date
, GREATEST('10:00:00', LEAST('18:00:00', TIME(Createddate))) start_time
, GREATEST('10:00:00', LEAST('18:00:00', TIME(Modifiedate))) end_time
FROM customerevent) dd ON dd.Id = d.Id GROUP BY d.Id;
present output:15.500
Expected output: 15H 30M
we have only 8 working hours per day so it is 15.500
Try This out
CREATE TABLE
customerevent (
id int NOT NULL,
Createddate CURRENT_TIMESTAMP() NULL,
Modifiedate CURRENT_TIMESTAMP()) NULL, PRIMARY KEY (id)
)

MySQL Sub Query takes long time to respond

I've created 3 tables imei, post and view. I've some 1000 records in all the 3 tables. Now when I execute the b/m query, it tooks very long to respond.
Table design & sample data are given below:
CREATE TABLE IF NOT EXISTS `imei` (
`imei_id` int(5) NOT NULL AUTO_INCREMENT,
`imei_no` varchar(30) NOT NULL,
`imei_net` varchar(30) NOT NULL,
`date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`imei_id`),
UNIQUE KEY `imei_no` (`imei_no`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1346 ;
CREATE TABLE IF NOT EXISTS `post` (
`post_id` int(5) NOT NULL AUTO_INCREMENT,
`post_title` varchar(60) NOT NULL,
`post_desc` varchar(500) NOT NULL,
`post_author` varchar(30) NOT NULL DEFAULT 'Admin',
`user_id` int(10) NOT NULL DEFAULT '1',
`date` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`post_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=876 ;
CREATE TABLE IF NOT EXISTS `view` (
`view_id` int(5) NOT NULL AUTO_INCREMENT,
`post_id` int(11) NOT NULL,
`imei_id` varchar(30) NOT NULL,
`status` varchar(10) NOT NULL,
`date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`view_id`),
UNIQUE KEY `imei_id` (`imei_id`,`post_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=13706 ;
Values Inside table:
IMEI:
INSERT INTO `imei` (`imei_id`, `imei_no`, `imei_net`, `date`) VALUES
(1, '123456789012345', 'Airtel', '2015-08-06 07:39:47'),
(2, '234567890123456', 'Aircel', '2015-08-06 06:08:33')
POST:
INSERT INTO `post` (`post_id`, `post_title`, `post_desc`, `post_author`, `user_id`, `date`) VALUES
(1, 'NSC Rate Down', 'NSC rates are getting down from today', 'Admin', 1, '2015-07-08 05:29:54'),
(2, 'NCDEX offers cashback', 'NCDEX offers cashback for the previous users', 'Admin', 1, '2015-07-08 05:30:01')
VIEW:
INSERT INTO `view` (`view_id`, `post_id`, `imei_id`, `status`, `date`) VALUES
(1, 1, '1', '1', '2015-08-08 05:04:38'),
(7, 2, '1', '1', '2015-08-08 07:55:25')
Query to Execute:
SELECT
*
FROM
(
SELECT
i.imei_id,
i.imei_no,
p.post_id,
p.post_title,
p.post_desc,
p.date,
1 AS STATUS
FROM
imei i,
post p,
VIEW v
WHERE
i.imei_id = v.imei_id
AND p.post_id = v.post_id
AND i.imei_no = 356554064098771
UNION
SELECT
i.imei_id,
i.imei_no,
p.post_id,
p.post_title,
p.post_desc,
p.date,
0 AS STATUS
FROM
imei i,
post p
WHERE
i.imei_no = 356554064098771
AND p.post_id NOT IN (
SELECT
v.post_id
FROM
imei i,
post p,
VIEW v
WHERE
p.post_id = v.post_id
AND v.imei_id = (
SELECT
i.imei_id
FROM
imei i
WHERE
imei_no = 356554064098771
)
)
) AS temp
WHERE
date >= DATE_SUB(
(
SELECT
date
FROM
imei
WHERE
imei_no = 356554064098771
),
INTERVAL 1 WEEK
)
ORDER BY
date DESC
try this query SELECT post_id,post_title,post_desc,date,if((post_id in (SELECT post_id FROM view WHERE imei_id = (SELECT imei_id FROM imei WHERE imei_no=865645026396909))),1,0) as status FROM post

MySQL Need advice on Query

I want to fetch latest 3 news from each news type.
CREATE TABLE IF NOT EXISTS `news` (
`news_id` int(8) NOT NULL AUTO_INCREMENT,
`news_heading` tinytext NOT NULL,
`news_description` text NOT NULL,
`news_date` date DEFAULT NOT NULL,
`news_type` tinyint(1) NOT NULL COMMENT '0- PEP|1 - MEDIA|2 - CONSULTING',
`created_date` datetime NOT NULL,
`modified_date` datetime NULL,
`display` tinyint(1) NOT NULL COMMENT '0- ON | 1 -OFF',
PRIMARY KEY (`news_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=2 ;
Below Query will give me only 1 latest news from all type. Suggest me how we can achieve for top 3 from each type
SELECT * FROM (
SELECT * FROM `news`
ORDER BY `created_date` DESC
) AS TBL
GROUP BY `news_type`
Try this:
SELECT news_id, news_heading, news_description, news_date,
news_type, created_date, modified_date, display
FROM (SELECT news_id, news_heading, news_description, news_date,
news_type, created_date, modified_date, display,
IF(#news_type = #news_type:=news_type, #id:=#id+1, #id:=1) AS id
FROM news, (SELECT #id:=1, #news_type:=0) A
ORDER BY news_type, created_date DESC
) AS A
WHERE id <= 3;

select from multiple tables but ordering by a datetime field

I have 3 tables that are unrelated (related that each contains data for a different social network). Each has a datetime field dated- I'm already grouping by hour as you can see below (this one below for linked_in)
SELECT count(*), date_format(dated, '%Y:%m:%d %H') as hour
FROM upd8r_linked_in_accts
WHERE CAST(dated AS DATE) = '".$start_date."'
GROUP BY hour
I would like to know how to do a total across all 3 networks- the tables for the three are
CREATE TABLE IF NOT EXISTS `upd8r_facebook_accts` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`owner_id` varchar(50) NOT NULL,
`user_id` int(11) NOT NULL,
`fb_id` bigint(30) NOT NULL,
`dated` datetime NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=80 ;
CREATE TABLE IF NOT EXISTS `upd8r_linked_in_accts` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`owner_id` varchar(50) NOT NULL,
`user_id` int(11) NOT NULL,
`linked_in` varchar(200) NOT NULL,
`oauth_secret` varchar(100) NOT NULL,
`first_count` int(11) NOT NULL,
`second_count` int(11) NOT NULL,
`dated` datetime NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=200 ;
CREATE TABLE IF NOT EXISTS `upd8r_twitter_accts` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`owner_id` varchar(50) NOT NULL,
`user_id` int(11) NOT NULL,
`twitter` varchar(200) NOT NULL,
`twitter_secret` varchar(100) NOT NULL,
`dated` datetime NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=9 ;
something like this ?
(SELECT count(*), date_format(dated, '%Y:%m:%d %H') as hour
FROM upd8r_linked_in_accts
WHERE CAST(dated AS DATE) = '".$start_date."')
UNION ALL
(SELECT count(*), date_format(dated, '%Y:%m:%d %H') as hour
FROM upd8r_facebook_accts
WHERE CAST(dated AS DATE) = '".$start_date."')
UNION ALL
(SELECT count(*), date_format(dated, '%Y:%m:%d %H') as hour
FROM upd8r_twitter_accts
WHERE CAST(dated AS DATE) = '".$start_date."')
UNION ALL
GROUP BY hour
update
the data in the actual database is not related by any pk or fk but the data is related that each table represents a user registering for a social network through the application and therefore i need to show the amount of users registered per hour across all three tables
update 2
the output of the query should show %Y:%m:%d %H and the amount of users registered (records created) that hour across the three tables.. each hour returning a new row (ordered by the time)
You are close to the solution
select t1.hourx, sum(t1.column1)
from (
(
SELECT count(*) as column1, date_format(dated, '%Y:%m:%d %H') as hourx
FROM upd8r_linked_in_accts
WHERE CAST(dated AS DATE) = '".$start_date."'
GROUP BY hourx
)
UNION ALL
(
SELECT count(*) as column1, date_format(dated, '%Y:%m:%d %H') as hourx
FROM upd8r_facebook_accts
WHERE CAST(dated AS DATE) = '".$start_date."'
GROUP BY hourx
)
UNION ALL
(
SELECT count(*) as column1, date_format(dated, '%Y:%m:%d %H') as hourx
FROM upd8r_twitter_accts
WHERE CAST(dated AS DATE) = '".$start_date."'
GROUP BY hourx
)
) t1
GROUP BY t1.hourx
I use 'hourx' to avoid reserve words, maybe not necessary.
I hope this works.
[ADD] This solution is called 'inline view'. You can google for that. It is supported by most of databases (mysql, oracle mssql and etc)