下一个问题是桌子。我需要使用一个sql查询将下一个表转换为另一个表:
id | idal | date | time | idaction
----- | ------ | ----------- | ------------ | ----------
1001 | 1 | 2016-08-1 | 13:30:39 | 1
1002 | 1 | 2016-08-1 | 13:42:02 | 2
1003 | 1 | 2016-08-1 | 13:42:04 | 1
1004 | 1 | 2016-08-1 | 13:42:06 | 8
1005 | 1 | 2016-08-1 | 13:44:04 | 9
1006 | 1 | 2016-08-1 | 13:44:06 | 8
1007 | 2 | 2016-08-1 | 14:30:39 | 1
1008 | 2 | 2016-08-1 | 14:42:02 | 2
1009 | 2 | 2016-08-1 | 14:42:06 | 8
1010 | 3 | 2016-08-1 | 15:00:01 | 1
1011 | 3 | 2016-08-1 | 15:01:43 | 2
我想得到的结果是下一个:
idal | dt_act1 | dt_act8 |
-------------------------------------------------
1 | 2016-08-1 13:30:39 | 2016-08-1 13:42:06
2 | 2016-08-1 14:30:39 | 2016-08-1 14:42:06
下面是这个复杂查询的含义:我想为每组得到相同的idal值(我们得到了1、2和3),只有那些至少包含idaction=1和8的值(在我们的示例中,只有idal 1和2包含这两个值)。同时,结果字段dt_act1和dt_act8是一个日期时间字段,在主表中它被分为日期和时间字段(可以使用concat mysql函数将其连接到数据时间字段中,这没问题)。如您所注意到的,dt_act1是idaction=1的同一个idal值的每组的最短日期时间。对于字段dt_act8相同,但对于idaction=8。如果没有包含idaction 8和1的idal组(在本例中,idal=3),则不显示此行。
我的解决方案不起作用:
SELECT t1.idal, t1.dt AS dt_act1, t2.dt AS dt_act8
FROM
(SELECT tt1.idal, CONCAT(tt1.`date`, ' ', tt1.`time`) AS dt FROM `table` tt1 (*)
HAVING dt = (SELECT MIN(CONCAT(tt2.`date`, ' ' , tt2.`time`))
FROM `table` tt2 WHERE tt1.idal=tt2.idal AND tt1.idaction=1
)
) t1
INNER JOIN
(SELECT tt3.idal, CONCAT(tt3.`date`, ' ', tt3.`time`) AS dt FROM `table` tt3 (**)
HAVING dt = (SELECT MIN(CONCAT(tt4.`date`, ' ' , tt4.`time`))
FROM `table` tt4 WHERE tt3.idal=tt4.idal AND tt3.idaction=8
)
) t2
ON t1.idal=t2.idal
这应该不够但不管用。
怎么做?
解决方案:在(*)和(*)之后分别保留“WHERE tt1.idaction=1”和“WHERE tt3.idaction=8”。
最佳答案
我将在if()
表达式中使用条件语句(case
或min()
)来获取相关idactions
的最小值然后使用having
子句来删除没有两个idactions
的数据的记录。
架构:
create table yourtable
( `id` int not null,
`idal` int not null,
`date` date not null, -- don't name columns like this
`time` time not null, -- don't name columns like this
`idaction` int not null
);
insert yourtable values
(1001,1,'2016-08-1','13:30:39',1),
(1002,1,'2016-08-1','13:42:02',2),
(1003,1,'2016-08-1','13:42:04',1),
(1004,1,'2016-08-1','13:42:06',8),
(1005,1,'2016-08-1','13:44:04',9),
(1006,1,'2016-08-1','13:44:06',8),
(1007,2,'2016-08-1','14:30:39',1),
(1008,2,'2016-08-1','14:42:02',2),
(1009,2,'2016-08-1','14:42:06',8),
(1010,3,'2016-08-1','15:00:01',1),
(1011,3,'2016-08-1','15:01:43',2);
查询:
select idal,
min(if(idaction=1,concat(`date`, ' ', `time`),null)) as dt_act1,
min(if(idaction=8,concat(`date`, ' ', `time`),null)) as dt_act8
from yourtable
group by idal
having dt_act1 is not null and dt_act8 is not null;
结果:
+------+---------------------+---------------------+
| idal | dt_act1 | dt_act8 |
+------+---------------------+---------------------+
| 1 | 2016-08-01 13:30:39 | 2016-08-01 13:42:06 |
| 2 | 2016-08-01 14:30:39 | 2016-08-01 14:42:06 |
+------+---------------------+---------------------+
关于mysql - 在MySQL中通过最少的日期将一行转换为两行,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/40243657/