这是一个简单的表格,用于描述日历中的事件:
Event
--------------------
Id int
DayId int # Foreign key to Day table
Title varchar(32)
Start datetime
Finish datetime
获取一些结果集的任意SELECT语句:
select
Id,
DayId,
Title,
Start,
Finish
from Event
where Start > now()
order by Start
上述选择查询将来会返回所有事件,这是不受欢迎的。但是使用limit
意味着您需要知道要限制的数量。
我希望能够选择具有相同DayId
值的前X行。
示例结果:
Id: 26, DayId: 08, Title: "Foo", Start: "2012-03-19 23:00:00"
Id: 27, DayId: 08, Title: "Bar", Start: "2012-03-20 00:00:00"
Id: 28, DayId: 09, Title: "Baz", Start: "2012-03-21 09:00:00"
Id: 29, DayId: 10, Title: "Barbaz", Start: "2012-03-22 11:00:00"
Id: 30, DayId: 09, Title: "Fooboo", Start: "2012-03-25 15:00:00"
假设上面的查询返回了这样的结果集,我正在寻找的查询只返回前两个行,因为它们是下一个发生的事件大卫·
但是,在3月19日之后,Start > now()
条件将返回不同的结果集:
Id: 28, DayId: 09, Title: "Baz", Start: "2012-03-21 09:00:00"
Id: 29, DayId: 10, Title: "Barbaz", Start: "2012-03-22 11:00:00"
Id: 30, DayId: 09, Title: "Fooboo", Start: "2012-03-25 15:00:00"
在这种情况下,结果应该只返回第一个行。请注意(出于解释目的),最后一个结果 具有相同的DayId,但由于它由不同的DayId分隔,因此应该忽略它。
答案 0 :(得分:1)
这可能不是达到预期结果的最佳方式,但它可以起作用:
select
Id,
DayId,
Title,
Start,
Finish
from Event
where Start > now(), AND DayId IN (SELECT DayId FROM Event WHERE Start > now() ORDER BY Start)
order by Start
刚才意识到你不能在子查询上使用LIMIT,现在这个答案将不起作用
答案 1 :(得分:1)
尝试一下:
select id, dayid, title start from (
select id,
@equal := @equal and dayId = @dayId ShouldReturn,
@dayId := dayId as dayId,
title,
start
from t, (
select @dayId := dayid, @equal := true from t
where start = (
select min(start) from t
where start > now()
)) init
where start > now()
order by start
) as final
where ShouldReturn
答案 2 :(得分:1)
据我所知,你希望所有的行都带有"第一个"大卫·。那怎么样呢
SELECT
e1.Id,
e1.DayId,
e1.Title,
e1.Start,
e1.Finish
FROM Event e1.
LEFT JOIN Event e2 ON e2.DayId>e1.DayId AND e2.Start<e1.Start
WHERE e1.DayId = (
SELECT MIN(DayId) FROM Event WHERE Start > now()
)
AND e2.id IS NULL
因此,您将在子查询的所有未来事件中获得第一个DayId,然后获取具有该DayId的所有事件。
答案 3 :(得分:0)
Chevi的答案几乎是完美的。它应该工作,但MySQL有一个限制,即无法在子查询中使用limit
。但是一个简单的解决方法是可能的:
select
Id,
DayId,
Title,
Start,
Finish
from Event
where Start > now(),
and DayId in (
-- Prepare yourself for a mega-hack!
select * from (
select `DayId`
from Event
where Start > now
order by Start
limit 1
-- You are allowed a limit here for some reason
) alias
)
order by Start
这个 工作,但是作为表别名的子查询似乎不是一个非常理想的解决方案,所以这个答案不会被标记为已回答,以防有人可以帮助回答问题更好。
答案 4 :(得分:0)
SELECT
e.*
FROM
Event AS e
JOIN
( SELECT DayId
FROM Event
WHERE Start > NOW()
ORDER BY Start
LIMIT 1
) AS good
ON e.Start > NOW()
AND e.Start < COALESCE(
( SELECT Start
FROM Event
WHERE Start > NOW()
AND DayId <> good.DayId
ORDER BY Start
LIMIT 1
)
, '9999-12-31')
ORDER BY
e.Start
或:
SELECT
e.*
FROM
Event AS e
CROSS JOIN
( SELECT Start
FROM
Event AS ee
CROSS JOIN
( SELECT DayId
FROM Event
WHERE Start > NOW()
ORDER BY Start
LIMIT 1
) AS good
WHERE Start > NOW()
AND ee.DayId <> good.DayId
ORDER BY Start
LIMIT 1
) AS bad
WHERE
e.Start > NOW()
AND
e.Start < COALESCE(bad.Start, '9999-12-31')
ORDER BY
e.Start