Mysql Query Group by Last记录和第一条记录

时间:2016-06-06 06:11:20

标签: mysql group-by

我有2个表,状态表与配置文件表连接。配置文件表存储唯一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     |

我想尝试分组第一个日期和分组到最后一个statusType

查询结果将是:

--------------------------------------------------------------------
| 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

但是它会返回上次日期和最后的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     |

2 个答案:

答案 0 :(得分:1)

我想你可能正在寻找这样的东西:

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`

查询使用派生表,该表返回每date的最小和最大tagId值。使用这些值,我们可以加入Status表,并从最小}记录中获取dateheightweight最大 Status值的date记录的em> StatusType Status值。

答案 1 :(得分:1)

不确定你是否想要这个,但试试看,希望我不要误解你的问题;)

SQL Fiddle

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')
;

查询1

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

<强> Results

| 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是每个组的最后一条记录,如果您想要heightweight列,请选择一个他们喜欢你。

此外,您可left joinprofile查询所有查询,然后您可以获得tagId = 106,但此记录会为null列提供datestatusType

相关问题