2016-06-06 2 views
2

У меня есть 2 таблицы, таблица состояний которых связана с таблицей профилей. В таблице профилей хранится уникальная таблица tagId и таблица состояний, в которой хранится множественная запись дубликата tagid. Я хочу показать группу по последней записи tagid и первой записи.Группа запросов Mysql по последней записи и первой записи

Таблица: Профиль Примечание: 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  | 
+0

Что такое 'height' и' weight'? – Blank

+0

забудьте о высоте, весе @Reno –

+0

Я просто этого не понимаю, но, возможно, было легче понять до – Strawberry

ответ

1

I думаю, что вы, вероятно, ищете что-то вроде этого:

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 столу и получить date, height и weight значения из Status записи, имеющей значение минимумdate иStatusType значение для Status записи, имеющей максимальнуюdate значение .

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 | 

Subquery f первая запись по каждой группе и l последняя запись по каждой группе, и если вы хотите height или weight колонки, пожалуйста, выберите один из них, которые вы предпочитаете к.

Также вы можете left join это все запросы к profile, то вы можете получить tagId = 106, но эта запись даст вам null для столбца date и statusType.

Смежные вопросы