按最后一条记录和第一条记录划分的Mysql查询组

按最后一条记录和第一条记录划分的Mysql查询组,mysql,group-by,Mysql,Group By,我有两个表,其中状态表与配置文件表相连接。配置文件表存储唯一的tagId和状态表存储多个重复的tagId条目。我想按tagid的最后一条记录和第一条记录显示组 表:概况 注意:tagId是唯一的 -------------------------------------------------------------------- | tagId(PK) | blah2 | blah3 | blah4 | ---------------------------------------------

我有两个表,其中状态表与配置文件表相连接。配置文件表存储唯一的tagId和状态表存储多个重复的tagId条目。我想按tagid的最后一条记录和第一条记录显示组

表:概况 注意:tagId是唯一的

--------------------------------------------------------------------
| 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就是不知道,但在没有强制规定身高、体重之前,也许更容易理解,跳过这个专栏@草莓