将查询扩展到 WHERE 子句中指定的范围之外
必须有更好的方法来编写这个查询。
我想选择一对日期之间的所有数据。 理想情况下,结果集的第一行和最后一行是 WHERE 子句中指定的行。 如果这些行不存在,我希望请求范围之前和之后的行。
举个例子:
如果我的数据是:
...
135321, 20090311 10:15:00
135321, 20090311 10:45:00
135321, 20090311 11:00:00
135321, 20090311 11:15:00
135321, 20090311 11:30:00
135321, 20090311 12:30:00
...
查询是:
SELECT *
FROM data_bahf
WHERE param_id = 135321
AND datetime >= '20090311 10:30:00'
AND datetime <= '20090311 12:00:00'
我希望返回的数据包含 10:15 的行和 12:30 的行。 不仅仅是那些严格满足 WHERE 子句的情况。
这是我想出的最好的办法。
SELECT * FROM (
SELECT *
FROM data_bahf
WHERE param_id = 135321
AND datetime > '20090311 10:30:00'
AND datetime < '20090311 12:00:00'
UNION
(
SELECT * FROM data_bahf
WHERE param_id = 135321
AND datetime <= '20090311 10:30:00'
ORDER BY datetime desc
LIMIT 1
)
UNION
(
SELECT * FROM data_bahf
WHERE param_id = 135321
AND datetime >= '20090311 12:00:00'
ORDER BY datetime asc
LIMIT 1
)
)
AS A
ORDER BY datetime
(暂时忽略 SELECT * 的使用)
编辑: 我有 param_id、datetime 和 (param_id, datetime) 的索引
There must be a better way of writing this query.
I want to select all the data between a pair of dates. Ideally the first and last rows of the result set would be those specifed in the WHERE clause. If those rows don't exist, I want the rows preceeding and following the requested range.
An example:
If my data is:
...
135321, 20090311 10:15:00
135321, 20090311 10:45:00
135321, 20090311 11:00:00
135321, 20090311 11:15:00
135321, 20090311 11:30:00
135321, 20090311 12:30:00
...
And the query is:
SELECT *
FROM data_bahf
WHERE param_id = 135321
AND datetime >= '20090311 10:30:00'
AND datetime <= '20090311 12:00:00'
I want the returned data to include the row at 10:15, and that of 12:30. Not just those that strictly meet the WHERE clause.
This is the best I've come up with.
SELECT * FROM (
SELECT *
FROM data_bahf
WHERE param_id = 135321
AND datetime > '20090311 10:30:00'
AND datetime < '20090311 12:00:00'
UNION
(
SELECT * FROM data_bahf
WHERE param_id = 135321
AND datetime <= '20090311 10:30:00'
ORDER BY datetime desc
LIMIT 1
)
UNION
(
SELECT * FROM data_bahf
WHERE param_id = 135321
AND datetime >= '20090311 12:00:00'
ORDER BY datetime asc
LIMIT 1
)
)
AS A
ORDER BY datetime
(Ignore the use of SELECT * for now)
EDIT:
I have indexes on param_id, datetime, and (param_id, datetime)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我想说的是:
编辑:添加后备。
当没有与子查询匹配的行时,将产生
NULL
值,必须使用ISNULL()
或BETWEEN
捕获该值> 运算符将失败,主查询将根本不返回任何行。I'd say this:
EDIT: Fallback added.
When there is no row matching the sub-query, it will result in a
NULL
value, which must be caught byISNULL()
or theBETWEEN
operator will fail and the main query will return no rows at all.首先,确保您在
(param_id, datetime)
上有一个复合索引其次,像这样的查询:
刚刚检查,它的运行时间为
1.215 ms
对于200,000
行的示例表First, make sure that you have a composite index on
(param_id, datetime)
Second, query like this:
Just checked, it runs in
1.215 ms
for a sample table of200,000
rows