قم بتوسيع الاستعلام إلى ما هو أبعد من ذلك المحدد في جملة WHERE
-
22-07-2019 - |
سؤال
يجب أن تكون هناك طريقة أفضل لكتابة هذا الاستعلام.
أريد تحديد كافة البيانات بين زوج من التواريخ.من الناحية المثالية، سيكون الصفوف الأول والأخير من مجموعة النتائج هي تلك المحددة في جملة 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)
المحلول
أولاً، تأكد من أن لديك مركب مؤشر على (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
صفوف
نصائح أخرى
وأنا أقول هذا:
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
سوف تفشل، وسوف الاستعلام الرئيسي عودة أية صفوف على الإطلاق.