SQL ، order by - كيفية إعطاء المزيد من السلطة للأعمدة الأخرى؟
-
22-07-2019 - |
سؤال
لدي بيان SQL هذا:
SELECT * FROM converts
WHERE email='myemail@googlemail.com' AND status!='1'
ORDER BY date ASC, priority DESC
هذا مجرد طلبات حسب التاريخ ، لكنني أريد أن أعطي عمودتي "الأولوية" المزيد من السلطة. كيف يمكنني أن أفعل هذا؟
يجب أن تطلب حسب التاريخ أولاً ، ولكن إذا كان الوقت بين سجلين هو 10 أعمدة ، فأنا أريد أن تولى الأولوية. كيف يمكنني القيام بذلك في بيان SQL الخاص بي أو هل يجب أن يكون هذا في منطق التطبيق الخاص بي؟ كنت آمل أن أتمكن من القيام بذلك في بيان SQL الخاص بي.
شكرا لكم جميعا على أي مساعدة
المحلول
يمكنك تحديد الطلب "التاريخ" إلى قطع 10 دقائق ، فماذا عن الطلب حسب الأرض (UNIX_TIMESTAMP (تاريخ)/600) ، ثم بالأولوية
SELECT * FROM converts
WHERE email='myemail@googlemail.com' AND status!='1'
ORDER BY floor(unix_timestamp(date)/600) ASC, priority DESC
على الرغم من أن تواريخين لا يزالان لا يزالان أقل من 10 دقائق ، إلا أن "قطعتين" مختلفتين لمدة 10 دقائق. ربما يكون ذلك كافيًا ، لكنني أعتقد أنه من الأفضل القيام بما تطلبه من خلال التطبيق.
(طلب التفسير الموسع ....)
خذ مرتين مما يمتد إلى حدود مدتها عشر دقائق ، مثل 9:09 و 9:11 اليوم:
- FLOOR (UNIX_TIMESTAMP ('2009-03-16 09:09:00')/600) = 2061990
- FLOOR (UNIX_TIMESTAMP ('2009-03-16 09:11:00')/600) = 2061991
لنفترض أن لديك صف أولوية أعلى لـ 09:11 من 09:09 - سيظل يظهر بعد، بعدما الصف 09:09 لأنه سقط في الجزء 10 دقائق القادمة ، على الرغم من أنه كان مختلفين دقيقتين فقط.
لذلك هذا النهج هو تقريب ، لكنه لا يحل المشكلة كما هو مذكور في الأصل.
الطريقة التي ذكرت بها مشكلتك ، يمكن أن يظهر صف الأولوية العالي قبل تسجيل عدة ساعات (أو أيام ، أو شهور!) في وقت سابق ، طالما كانت هناك سلسلة غير منقطعة من الصف الأولوية المنخفضة مع فاصل أقل من 10 دقائق.
نصائح أخرى
سيكون هناك تباين آخر:
SELECT * FROM converts
WHERE email='myemail@googlemail.com' AND status!='1'
ORDER BY (unix_timestamp(date)/60) - priority
لا يزال ليس بالضبط ما تحتاجه ، ولكن قريب جدا.
على افتراض أنك تعني حقًا "الوقت بين سجلين هو 10 أعمدة [أو أقل] ثم أريد أن تتولى الأولوية؟
ثم فقط فرز لمدة عشر دقائق كتل ، ثم بأولوية ...
يختار ...
أمر من قبل Datediff (دقيقة ، 0 ، تاريخ) / 10 ، الأولوية
يمكنك ضبط القيمة 0 للتحكم في المكان الذي يبدأ فيه كل "كتلة دقيقة" وتوقف ... إذا لم يكن لدى MySQL وظيفة Datediff ، فاستخدم أي تعبير في MySQL الذي يوفر عددًا من الدقائق منذ وقت مرجعي ...
إذا كنت تستخدم SQL Server 2005/88 ، فيمكنك إنجاز هذه المهمة باستخدام CTE العودية. يرجى ملاحظة أنني كتبت هذا النص في المفكرة ولم يتم اختباره بعد. بمجرد أن تتاح لي الفرصة لاختبار نتائج الاستعلام ، سأقوم بتحديث CTE إذا كان هناك خطأ أو إزالة هذا التعليق تمامًا.
مع date_cte
كما
(SELECT *
, 'sequential_order' = ROW_NUMBER() OVER
(PARTITION BY email
ORDER BY date ASC, priority DESC)
FROM converts
WHERE email = 'myemail@googlemail.com'
AND status <> '1')
, و Recursive_Date_CTE
كما
(SELECT dc1.*
, 'sort_level' = 1
FROM date_cte dc1
WHERE sequential_order = 1
UNION
SELECT dc1.*
, 'sort_level' = CASE
WHEN DATEDIFF(MINUTE, dc1.date, dc2.date) <= 10 THEN sort_level
ELSE sort_level + 1 END
LEFT JOIN date_cte dc2
ON dc1.sequential_order = dc2.sequential_order - 1
WHERE dc1.sequential_order > 1)
تحديد *
من Recursive_Date_CTE
اطلب بواسطة Sort_level ASC
, priority DESC
ما عليك سوى تغيير الطلب أو colums في بيان الطلب
SELECT * FROM converts WHERE email='myemail@googlemail.com' AND status!='1' ORDER BY priority DESC, date ASC