必须有更好的方法来编写此查询。
我想选择一对日期之间的所有数据。理想情况下,结果集的第一行和最后一行将是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)
上有索引答案 0 :(得分:3)
我会这样说:
SELECT
o.*
FROM
data_bahf o
WHERE
o.param_id = 135321
AND o.datetime BETWEEN
ISNULL(
(
SELECT MAX(datetime)
FROM data_bahf i
WHERE i.param_id = 135321 AND i.datetime <= '20090311 10:30:00'
),
'0001-01-01 00:00:00'
)
AND
ISNULL(
(
SELECT MIN(datetime)
FROM data_bahf i
WHERE i.param_id = 135321 AND i.datetime >= '20090311 12:00:00'
),
'9999-12-31 23:59:59'
)
编辑:后备补充。
如果没有与子查询匹配的行,则会生成NULL
值,该值必须由ISNULL()
捕获,否则BETWEEN
运算符将失败,主查询将返回no完全没有行。
答案 1 :(得分:2)
首先,确保(param_id, datetime)
其次,查询如下:
SELECT *
FROM data_bahf
WHERE param_id = 135321
AND datetime BETWEEN
COALESCE(
(
SELECT MAX(datetime)
FROM data_bahf
WHERE param_id = 135321
AND datetime <= '2009-01-01 00:00:00'
), '0001-01-01')
AND
COALESCE(
(
SELECT MIN(datetime)
FROM data_bahf
WHERE param_id = 135321
AND datetime >= '2009-01-02 00:00:00'
), '9999-01-01')
刚刚选中,它会在1.215 ms
中运行200,000
行