سكل حدد العناصر حيث مجموع الحقل أقل من ن
-
12-12-2019 - |
سؤال
وبالنظر إلى أن لدي جدول مع ما يلي ، محتوى بسيط جدا:
# select * from messages;
id | verbosity
----+-----------
1 | 20
2 | 20
3 | 20
4 | 30
5 | 100
(5 rows)
وأود أن حدد ن الرسائل ، التي مجموع الإسهاب هو أقل من ذ (لأغراض الاختبار دعونا نقول أنه ينبغي أن يكون 70 ، ثم النتائج الصحيحة ستكون الرسائل مع معرف 1 ، 2 ، 3).من المهم حقا بالنسبة لي ، يجب أن يكون هذا الحل قاعدة بيانات مستقلة (يجب أن تعمل على الأقل على بوستغريس و سكليتي).
كنت أحاول مع شيء من هذا القبيل:
SELECT * FROM messages GROUP BY id HAVING SUM(verbosity) < 70;
ومع ذلك ، لا يبدو أنه يعمل كما هو متوقع ، لأنه لا يجمع في الواقع كل القيم من عمود الإسهاب.
سأكون ممتنا جدا لأي تلميحات / مساعدة.
المحلول
SELECT m.id, sum(m1.verbosity) AS total
FROM messages m
JOIN messages m1 ON m1.id <= m.id
WHERE m.verbosity < 70 -- optional, to avoid pointless evaluation
GROUP BY m.id
HAVING SUM(m1.verbosity) < 70
ORDER BY total DESC
LIMIT 1;
هذا يفترض فريدة من نوعها ، تصاعدي id
كما لديك في المثال الخاص بك.
في بوستغرس الحديثة - أو عموما مع سكل القياسية الحديثة (لكن لا في سكليتي):
بسيطة كت
WITH cte AS (
SELECT *, sum(verbosity) OVER (ORDER BY id) AS total
FROM messages
)
SELECT *
FROM cte
WHERE total <= 70
ORDER BY id;
كت العودية
يجب أن يكون أسرع للجداول الكبيرة حيث يمكنك استرداد مجموعة صغيرة فقط.
WITH RECURSIVE cte AS (
( -- parentheses required
SELECT id, verbosity, verbosity AS total
FROM messages
ORDER BY id
LIMIT 1
)
UNION ALL
SELECT c1.id, c1.verbosity, c.total + c1.verbosity
FROM cte c
JOIN LATERAL (
SELECT *
FROM messages
WHERE id > c.id
ORDER BY id
LIMIT 1
) c1 ON c1.verbosity <= 70 - c.total
WHERE c.total <= 70
)
SELECT *
FROM cte
ORDER BY id;
جميع الميزات القياسية ، باستثناء LIMIT
.
بالمعنى الدقيق للكلمة ، لا يوجد شيء مثل "قاعدة بيانات مستقلة".هناك العديد من معايير سكل ، ولكن لا ردبس يتوافق تماما. LIMIT
يعمل ل بوستغريزل و سكليتي (وبعض الآخرين).استخدام TOP 1
ل سكل سيرفر, rownum
لأوراكل.وهنا قائمة شاملة على ويكيبيديا.
ال سكل: 2008 القياسية سيكون:
...
FETCH FIRST 1 ROWS ONLY
...الذي يدعم كيو-ولكن لا يكاد أي ردبس أخرى.
البديل النقي الذي يعمل مع المزيد من الأنظمة هو لفه في استعلام فرعي و
SELECT max(total) FROM <subquery>
لكن هذا بطيء وغير عملي.
نصائح أخرى
سيعمل هذا ...
giveacodicetagpre.ومع ذلك، يجب أن تفهم أنه تم تصميم SQL بلغة قائمة على مجموعة، بدلا من واحدة تكرارية، لذلك صممت لعلاج البيانات كمجموعة، بدلا من التوالي على التوالي.