按最后一条记录和第一条记录划分的Mysql查询组
我有两个表,其中状态表与配置文件表相连接。配置文件表存储唯一的tagId和状态表存储多个重复的tagId条目。我想按tagid的最后一条记录和第一条记录显示组 表:概况 注意:tagId是唯一的按最后一条记录和第一条记录划分的Mysql查询组,mysql,group-by,Mysql,Group By,我有两个表,其中状态表与配置文件表相连接。配置文件表存储唯一的tagId和状态表存储多个重复的tagId条目。我想按tagid的最后一条记录和第一条记录显示组 表:概况 注意:tagId是唯一的 -------------------------------------------------------------------- | tagId(PK) | blah2 | blah3 | blah4 | ---------------------------------------------
--------------------------------------------------------------------
| tagId(PK) | blah2 | blah3 | blah4 |
--------------------------------------------------------------------
101 |
102 |
103 |
104 |
105 |
106 |
表:现状
--------------------------------------------------------------------
statusId | tagId | date | height| weight | statusType | blah2 |
--------------------------------------------------------------------
1 | 101 | 2010-01-01 | 5.6 | 300 | single |
2 | 102 | 2010-01-01 | 5.7 | 300 | single |
3 | 101 | 2015-01-01 | 5.6 | 310 | married |
4 | 103 | 2010-01-01 | 5.6 | 300 | single |
5 | 104 | 2010-01-01 | 5.6 | 300 | single |
6 | 101 | 2016-01-01 | 5.6 | 300 | pregnant |
7 | 101 | 2016-09-01 | 5.6 | 300 | delivery |
8 | 105 | 2010-01-01 | 5.6 | 300 | single |
我想尝试的是按第一个日期分组和按最后一个状态类型分组
查询结果为:
--------------------------------------------------------------------
| tagId | date | height| weight | statusType | blah2 |
--------------------------------------------------------------------
| 101 | 2010-01-01 | 5.6 | 300 | delivery |
| 102 | 2010-01-01 | 5.7 | 300 | single |
| 103 | 2010-01-01 | 5.6 | 300 | single |
| 104 | 2010-01-01 | 5.6 | 300 | single |
| 105 | 2010-01-01 | 5.6 | 300 | single |
但是我不能成功,我尝试了这个MySQL代码
SELECT DISTINCT Profile.TagId,Status.date,Status.StatusType,Status.height,Status.weight FROM Profile
LEFT JOIN Status ON Status.TagId = Profile.TagId
Where Status.StatusId In( Select Max(Status.StatusId) From Status Group By Status.TagId )
Group By Status.TagId ORDER BY Profile.TagId ASC, Status.TagId DESC
但它会返回last date和last statustype,如下所示
查询结果:
--------------------------------------------------------------------
| tagId | date | height| weight | statusType | blah2 |
--------------------------------------------------------------------
| 101 | 2016-09-01 | 5.6 | 300 | delivery |
| 102 | 2010-01-01 | 5.7 | 300 | single |
| 103 | 2010-01-01 | 5.6 | 300 | single |
| 104 | 2010-01-01 | 5.6 | 300 | single |
| 105 | 2010-01-01 | 5.6 | 300 | single |
我想你可能正在寻找这样的东西:
SELECT DISTINCT p.tagId,
smin.`date`, smin.height, smin.weight,
smax.StatusType
FROM Profile AS p
LEFT JOIN (
SELECT tagId, MAX(`date`) AS max_date, MIN(`date`) AS min_date
FROM Status
GROUP BY tagId
) AS s ON p.tagId = s.tagId
LEFT JOIN Status AS smin ON smin.tagId = p.tagId AND s.min_date = smin.`date`
LEFT JOIN Status AS smax ON smax.tagId = p.tagId AND s.max_date = smax.`date`
查询使用一个派生表,该表根据
tagId
返回最小值和最大值date
。使用这些值,我们可以连接回状态
表并获得日期
,状态
记录中具有最小日期
值的高度
和重量
值和具有最大日期
值的状态
记录的状态类型
值。不确定是否需要此值,请尝试,希望我没有弄错你的问题;)
MySQL 5.6安装程序:
CREATE TABLE status
(`statusId` int, `tagId` int, `date` date, `height` int, `weight` int, `statusType` varchar(8))
;
INSERT INTO status
(`statusId`, `tagId`, `date`, `height`, `weight`, `statusType`)
VALUES
(1, 101, '2010-01-01', 5.6, 300, 'single'),
(2, 102, '2010-01-01', 5.7, 300, 'single'),
(3, 101, '2015-01-01', 5.6, 310, 'married'),
(4, 103, '2010-01-01', 5.6, 300, 'single'),
(5, 104, '2010-01-01', 5.6, 300, 'single'),
(6, 101, '2016-01-01', 5.6, 300, 'pregnant'),
(7, 101, '2016-09-01', 5.6, 300, 'delivery'),
(8, 105, '2010-01-01', 5.6, 300, 'single')
;
select f.`tagId`, date_format(l.`date`, '%Y-%m-%d') as `date`, f.`statusType`
from (
select s.*
from `status` s
inner join (
select max(`statusId`) as `statusId`, `tagId`
from `status`
group by `tagId`) t on s.`statusId` = t.`statusId` and s.`tagId` = t.`tagId`
) f
inner join (
select s.*
from `status` s
inner join (
select min(`statusId`) as `statusId`, `tagId`
from `status`
group by `tagId`) t on s.`statusId` = t.`statusId` and s.`tagId` = t.`tagId`
) l on f.`tagId` = l.`tagId`
order by tagId
| tagId | date | statusType |
|-------|------------|------------|
| 101 | 2010-01-01 | delivery |
| 102 | 2010-01-01 | single |
| 103 | 2010-01-01 | single |
| 104 | 2010-01-01 | single |
| 105 | 2010-01-01 | single |
查询1:
CREATE TABLE status
(`statusId` int, `tagId` int, `date` date, `height` int, `weight` int, `statusType` varchar(8))
;
INSERT INTO status
(`statusId`, `tagId`, `date`, `height`, `weight`, `statusType`)
VALUES
(1, 101, '2010-01-01', 5.6, 300, 'single'),
(2, 102, '2010-01-01', 5.7, 300, 'single'),
(3, 101, '2015-01-01', 5.6, 310, 'married'),
(4, 103, '2010-01-01', 5.6, 300, 'single'),
(5, 104, '2010-01-01', 5.6, 300, 'single'),
(6, 101, '2016-01-01', 5.6, 300, 'pregnant'),
(7, 101, '2016-09-01', 5.6, 300, 'delivery'),
(8, 105, '2010-01-01', 5.6, 300, 'single')
;
select f.`tagId`, date_format(l.`date`, '%Y-%m-%d') as `date`, f.`statusType`
from (
select s.*
from `status` s
inner join (
select max(`statusId`) as `statusId`, `tagId`
from `status`
group by `tagId`) t on s.`statusId` = t.`statusId` and s.`tagId` = t.`tagId`
) f
inner join (
select s.*
from `status` s
inner join (
select min(`statusId`) as `statusId`, `tagId`
from `status`
group by `tagId`) t on s.`statusId` = t.`statusId` and s.`tagId` = t.`tagId`
) l on f.`tagId` = l.`tagId`
order by tagId
| tagId | date | statusType |
|-------|------------|------------|
| 101 | 2010-01-01 | delivery |
| 102 | 2010-01-01 | single |
| 103 | 2010-01-01 | single |
| 104 | 2010-01-01 | single |
| 105 | 2010-01-01 | single |
:
CREATE TABLE status
(`statusId` int, `tagId` int, `date` date, `height` int, `weight` int, `statusType` varchar(8))
;
INSERT INTO status
(`statusId`, `tagId`, `date`, `height`, `weight`, `statusType`)
VALUES
(1, 101, '2010-01-01', 5.6, 300, 'single'),
(2, 102, '2010-01-01', 5.7, 300, 'single'),
(3, 101, '2015-01-01', 5.6, 310, 'married'),
(4, 103, '2010-01-01', 5.6, 300, 'single'),
(5, 104, '2010-01-01', 5.6, 300, 'single'),
(6, 101, '2016-01-01', 5.6, 300, 'pregnant'),
(7, 101, '2016-09-01', 5.6, 300, 'delivery'),
(8, 105, '2010-01-01', 5.6, 300, 'single')
;
select f.`tagId`, date_format(l.`date`, '%Y-%m-%d') as `date`, f.`statusType`
from (
select s.*
from `status` s
inner join (
select max(`statusId`) as `statusId`, `tagId`
from `status`
group by `tagId`) t on s.`statusId` = t.`statusId` and s.`tagId` = t.`tagId`
) f
inner join (
select s.*
from `status` s
inner join (
select min(`statusId`) as `statusId`, `tagId`
from `status`
group by `tagId`) t on s.`statusId` = t.`statusId` and s.`tagId` = t.`tagId`
) l on f.`tagId` = l.`tagId`
order by tagId
| tagId | date | statusType |
|-------|------------|------------|
| 101 | 2010-01-01 | delivery |
| 102 | 2010-01-01 | single |
| 103 | 2010-01-01 | single |
| 104 | 2010-01-01 | single |
| 105 | 2010-01-01 | single |
子查询f
是每组的第一条记录,l
是每组的最后一条记录,如果您想要height
或weight
列,请选择您喜欢的其中一条
你也可以
left join
将所有查询加入profile
,然后你可以得到tagId
=106,但是这个记录会给你null
列date
和statusType
什么是height
和weight
?忘记身高,weight@RenoI就是不知道,但在没有强制规定身高、体重之前,也许更容易理解,跳过这个专栏@草莓