获取每个ID的第一行

时间:2011-04-22 12:33:26

标签: php mysql sql

今天,我想获取已选择或具有最近日期的列表中所有事件的列表。我实际上使用以下代码

SELECT choices.id AS id, events.id AS event_id,
events.owner_id, choices.selected, 
choices_dates.label AS events_date
FROM events
LEFT JOIN polls ON (events.id = polls.event_id)
LEFT JOIN choices ON (polls.id = choices.poll_id)
LEFT JOIN choices_dates ON (choices.id = choices_dates.choice_id)
WHERE polls.kind = 'date'
ORDER BY events.id, choices.selected DESC, events_date DESC;

我得到了这个结果:

id         event_id         owner_id         selected         events_date
2          1         1         0         2011-04-20 12:00:00
1          1         1         0         2011-04-20 00:00:00
7          2         1         0         2011-04-20 12:00:00
6          2         1         0         2011-04-20 00:00:00
13         3         1         0         2011-04-22 15:57:54
12         3         1         0         2011-04-20 12:00:00
11         3         1         0         2011-04-20 00:00:00

但这就是我想要的:

id         event_id         owner_id         selected         events_date
2          1         1         0         2011-04-20 12:00:00
7          2         1         0         2011-04-20 12:00:00
13         3         1         0         2011-04-22 15:57:54

我无法进行嵌套查询,因为我正在创建一个VIEW,并且group by给出了随机结果(我获取了event_id 1的第一行,以及event_id 2的最后一行,...)

现在,我可以使用php函数完成这项工作,但它不是优化,而且我的代码很脏。

有人知道如何使用一个出色的SQL函数吗?

谢谢, 凯文

编辑:我已经成功地做了我想做的事情:我使用了两种不同的视图:

创建VIEWview_events_maxAS 选择 events.id AS event_id, MAX(choices.selected)AS max_selected, MAX(choices_dates.label)AS max_events_date 来自事件 LEFT JOIN轮询ON(events.id = polls.event_id) LEFT JOIN选项ON(polls.id = choices.poll_id) LEFT JOIN choices_dates ON(choices.id = choices_dates.choice_id) WHERE polls.kind ='date' GROUP BY event_id

创建视图view_events_correct AS( 选择 choices.id AS id, events.id AS event_id, events.owner_id, choices.selected, choices_dates.label AS event_date 来自事件 LEFT JOIN轮询ON(events.id = polls.event_id) LEFT JOIN选项ON(polls.id = choices.poll_id) LEFT JOIN choices_dates ON(choices.id = choices_dates.choice_id INNER JOIN view_events_max ON(events.id = view_events_max.event_id AND(choices.selected = 1 OR(choices.selected = view_events_max.max_selected AND choices_dates.label = view_events_max.max_events_date))) )

谢谢大家的帮助,凯文

2 个答案:

答案 0 :(得分:1)

我知道在Oracle中你可以使用分析函数来做到这一点。我不知道mySql是否有类似内容...

select id, event_id, owner_id, selected, events_date from (
SELECT choices.id AS id, events.id AS event_id, events.owner_id as owner_id,
choices.selected as selected,
choices_dates.label AS events_date,
max(choices_date.label) over (partition by events.id) as max_events_date
FROM events LEFT JOIN polls ON (events.id = polls.event_id) LEFT JOIN choices ON
(polls.id = choices.poll_id) LEFT JOIN choices_dates ON (choices.id =
choices_dates.choice_id)
WHERE polls.kind = 'date') innerview
where events_date = max_events_date
order by event_id, selected DESC, events_date DESC;

答案 1 :(得分:0)

这样的事情(未经测试,缺少模式描述和数据库软件版本)是否有效?

select choices.id as id
     , events.id as event_id
     , events.owner_id
     , choices.selected
     , choices_dates.label as events_date
from
(
    SELECT events.id as max_event_id
         , max(choices_dates.label) as max_events_date
    FROM events
    LEFT JOIN polls ON (events.id = polls.event_id)
    LEFT JOIN choices ON (polls.id = choices.poll_id)
    LEFT JOIN choices_dates ON (choices.id = choices_dates.choice_id)
    WHERE polls.kind = 'date'
    GROUP BY events.id
) 
LEFT JOIN polls ON (events.id = polls.event_id)
LEFT JOIN choices ON (polls.id = choices.poll_id)
LEFT JOIN choices_dates ON (choices.id = choices_dates.choice_id)
where events_date = max_events_date
  and events.id = max_event_id