SQL数据透视和计算以字符串形式存储的日期之间的差异-MySQL
我有两张桌子。第一个称为SQL数据透视和计算以字符串形式存储的日期之间的差异-MySQL,mysql,sql,pivot,mariadb,Mysql,Sql,Pivot,Mariadb,我有两张桌子。第一个称为posts,第二个称为postmeta。(如果有人注意到,我正在使用Wordpress db,这对于这项任务来说并不重要) posts表如下所示(为此缩短) postETA表如下所示。日期格式为d.m.Y.G:i:s meta_id | post_id | meta_key | meta_value ------------------------------------------ 1 | 1 | from | 1.1.2017. 10:
posts
,第二个称为postmeta
。(如果有人注意到,我正在使用Wordpress db,这对于这项任务来说并不重要)
posts
表如下所示(为此缩短)
postETA
表如下所示。日期格式为d.m.Y.G:i:s
meta_id | post_id | meta_key | meta_value
------------------------------------------
1 | 1 | from | 1.1.2017. 10:00:00
2 | 1 | to | 1.1.2017. 16:00:00
3 | 2 | from | 2.1.2017. 12:00:00
4 | 2 | to | 2.1.2017. 15:00:00
在那些表中,ID
=post\u ID
。
想要得到的结果是下表中的date\u diff
是from
和to
之间的差异,必须通过SQL计算(date\u diff=to-from)。请注意,meta_key
被定义为VARCHAR
,meta_value
被定义为LONGTEXT
,这使得计算更加困难
ID | title | from | to | date_diff
------------------------------------------------------------------
1 | 1 | 1.1.2017. 10:00:00 | 1.1.2017. 16:00:00 | 6
2 | 1 | 2.1.2017. 12:00:00 | 2.1.2017. 15:00:00 | 3
这是我现在的代码。让行变成列对我来说有点问题,而且计算更麻烦
SELECT posts.ID, posts.post_title, postmeta.meta_key, postmeta.meta_value
FROM posts
INNER JOIN postmeta
ON posts.ID = postmeta.post_id
WHERE post_status = 'publish'
AND post_type = 'hours'
AND (postmeta.meta_key = 'from' OR postmeta.meta_key = 'to');
非常感谢。:) 您可以在POSTETA上使用自连接来获取两个分离的列 使用str_to_date转换日期中的字符串 对保留字(例如:from)使用适当的backtics 和TIMESTAMPDIFF,用于获取diff的小时数
SELECT
posts.ID
, posts.post_title
, str_to_date(table_from.meta_value, '%d.%m.%Y. %H:%i:%s') as `from`
, str_to_date(table_to.meta_value, '%d.%m.%Y. %H:%i:%s' ) as `to`
, TIMESTAMPDIFF(HOUR, str_to_date(table_from.meta_value, '%d.%m.%Y. %H:%i:%s') ,
str_to_date(table_to.meta_value, '%d.%m.%Y. %H:%i:%s' )) as diff
FROM posts
INNER JOIN postmeta table_from ON posts.ID = table_from.post_id and table_from.meta_key ='from'
inner join postmeta table_to ON posts.ID = table_to.post_id and table_to.meta_key ='to'
WHERE post_status = 'publish'
AND post_type = 'hours'
对于十进制,您可以使用
timestampdiff(分钟、开始日期、结束日期)/60作为diff,我希望它能有所帮助
SELECT
p.id,
p.post_title,
postmeta_temp.from,
postmeta_temp.to,
postmeta_temp.date_diff
FROM posts p
INNER JOIN (SELECT postmeta_from.post_id
AS post_id,
postmeta_from.meta_key
AS from,
postmeta_to.meta_key
AS to,
Date_diff(postmeta_to.meta_value,
postmeta_from.meta_value)
AS date_diff
FROM postmeta postmeta_from
INNER JOIN postmeta postmeta_to
ON postmeta_from.post_id = postmeta_to.post_id
AND postmeta_from.meta_key = 'from'
AND postmeta_to.meta_key = 'to') AS
postmeta_temp
ON p.id = postmeta_temp.post_id
例如(比斯盖里奇的方法慢,但更容易阅读…)
我把最后一部分留给读者作为一个(简单的)练习。对于每一个ID,我下次会用相同的ID和下一个日期检查
select pm.post_id as ID, pm.post_id as title, pm.metavalue as from,
(select x.metavalue from postmeta x where x.enter code herepost_id = pm.post_id and not x.meta_key = 'from')
as to ,
(select cast(x.metavalue as timestamp) - cast(pm.metavalue as timestamp) from postmeta x
where x.post_id = pm.post_id and not x.meta_key = 'from') as date_diff from
postmeta pm where pm.meta_key = 'from';
id | title | from | to | date_diff
----+-------+--------------------+--------------------+-----------
1 | 1 | 1.1.2017. 10:00:00 | 1.1.2017. 16:00:00 | 06:00:00
2 | 2 | 2.1.2017. 12:00:00 | 2.1.2017. 15:00:00 | 03:00:00
感谢您的回复,我尝试了代码,但是from、to和diff只有空值。在测试代码时,我注意到str_to_date返回空值,所以这可能是原因,但仍然不起作用,但是,它非常接近。可能是日期格式。。。年复一年地漏掉一点。。答案用点更新。如果使用24小时,格式必须为H而不是H。。回答UpdateEdit起作用,TIMESTAMPDIFF是否可以以小数形式显示小时,例如1.5小时,因为目前它只显示整小时我认为你的数据集出错了。什么是post_id=3!?!哦,对不起,错别字,是2:)草莓,谢谢你的回答,太棒了,不幸的是我只能把一个答案当作正确答案。你努力回答,所以我能做的最小的事情就是给它投票;)谢谢:)
DROP TABLE IF EXISTS posts;
CREATE TABLE posts
(id INT NOT NULL AUTO_INCREMENT PRIMARY KEY
,post_title VARCHAR(12) NOT NULL
,post_status VARCHAR(12) NOT NULL
,post_type VARCHAR(12) NOT NULL
);
INSERT INTO posts VALUES
(1,'One','publish','hours'),
(2,'Two','publish','hours');
DROP TABLE IF EXISTS postmeta;
CREATE TABLE postmeta
(meta_id INT NOT NULL AUTO_INCREMENT PRIMARY KEY
,post_id INT NOT NULL
,meta_key VARCHAR(12) NOT NULL
,meta_value VARCHAR(20) NOT NULL
);
INSERT INTO postmeta VALUES
(1,1,'from','1.1.2017. 10:00:00'),
(2,1,'to' ,'1.1.2017. 16:00:00'),
(3,2,'from','2.1.2017. 12:00:00'),
(4,2,'to' ,'2.1.2017. 15:00:00');
-- Date format is d.m.Y. H:i:s.
SELECT post_id
, MAX(CASE WHEN meta_key = 'from' THEN STR_TO_DATE(meta_value,'%d.%m.%Y. %H:%i:%s') END) `from`
, MAX(CASE WHEN meta_key = 'to' THEN STR_TO_DATE(meta_value,'%d.%m.%Y. %H:%i:%s') END) `to`
, TIMEDIFF(
MAX(CASE WHEN meta_key = 'to' THEN STR_TO_DATE(meta_value,'%d.%m.%Y. %H:%i:%s') END)
, MAX(CASE WHEN meta_key = 'from' THEN STR_TO_DATE(meta_value,'%d.%m.%Y. %H:%i:%s') END)
) date_diff
FROM postmeta
GROUP
BY post_id;
+---------+---------------------+---------------------+-----------+
| post_id | from | to | date_diff |
+---------+---------------------+---------------------+-----------+
| 1 | 2017-01-01 10:00:00 | 2017-01-01 16:00:00 | 06:00:00 |
| 2 | 2017-01-02 12:00:00 | 2017-01-02 15:00:00 | 03:00:00 |
+---------+---------------------+---------------------+-----------+
select pm.post_id as ID, pm.post_id as title, pm.metavalue as from,
(select x.metavalue from postmeta x where x.enter code herepost_id = pm.post_id and not x.meta_key = 'from')
as to ,
(select cast(x.metavalue as timestamp) - cast(pm.metavalue as timestamp) from postmeta x
where x.post_id = pm.post_id and not x.meta_key = 'from') as date_diff from
postmeta pm where pm.meta_key = 'from';
id | title | from | to | date_diff
----+-------+--------------------+--------------------+-----------
1 | 1 | 1.1.2017. 10:00:00 | 1.1.2017. 16:00:00 | 06:00:00
2 | 2 | 2.1.2017. 12:00:00 | 2.1.2017. 15:00:00 | 03:00:00