سؤال

لدي جدول MySQL يحتوي على 3000 صف تقريبًا لكل مستخدم.أحد الأعمدة عبارة عن حقل التاريخ والوقت، وهو قابل للتغيير، وبالتالي فإن الصفوف ليست بترتيب زمني.

أرغب في تصور توزيع الوقت في مخطط، لذلك أحتاج إلى عدد من نقاط البيانات الفردية.20 نقطة بيانات ستكون كافية.

يمكنني أن أفعل هذا:

select timefield from entries where uid = ? order by timefield;

وانظر إلى كل صف 150.

أو يمكنني إجراء 20 استعلامًا منفصلاً واستخدامه limit 1 و offset.

ولكن يجب أن يكون هناك حل أكثر فعالية.

هل كانت مفيدة؟

المحلول

كان Michal Sznajder على وشك الحصول عليه، ولكن لا يمكنك استخدام الأسماء المستعارة للأعمدة في جملة WHERE في SQL.لذلك عليك تغليفه كجدول مشتق.لقد جربت هذا وأرجع 20 صفًا:

SELECT * FROM (
    SELECT @rownum:=@rownum+1 AS rownum, e.*
    FROM (SELECT @rownum := 0) r, entries e) AS e2
WHERE uid = ? AND rownum % 150 = 0;

نصائح أخرى

شيء من هذا القبيل جاء إلى ذهني

select @rownum:=@rownum+1 rownum, entries.* 
from (select @rownum:=0) r, entries 
where uid = ? and rownum % 150 = 0

ليس لدي MySQL في يدي ولكن ربما سيساعد هذا ...

بقدر ما يتعلق بالتصور، أعلم أن هذه ليست العينات الدورية التي تتحدث عنها، لكنني سألقي نظرة على جميع الصفوف الخاصة بالمستخدم واختر مجموعة فاصل زمني، ومجموعها داخل المجموعات وأظهرها على رسم بياني شريطي أو ما شابه.وهذا من شأنه أن يظهر "توزيعًا" حقيقيًا، نظرًا لأن العديد من الأحداث خلال إطار زمني قد تكون مهمة.

SELECT DATEADD(day, DATEDIFF(day, 0, timefield), 0) AS bucket -- choose an appropriate granularity (days used here)
     ,COUNT(*)
FROM entries
WHERE uid = ?
GROUP BY DATEADD(day, DATEDIFF(day, 0, timefield), 0)
ORDER BY DATEADD(day, DATEDIFF(day, 0, timefield), 0)

أو إذا كنت لا تحب الطريقة التي يتعين عليك بها تكرار نفسك - أو إذا كنت تلعب باستخدام مجموعات مختلفة وتريد التحليل عبر العديد من المستخدمين بشكل ثلاثي الأبعاد (القياس في Z مقابل x وy uid وbucklo):

SELECT uid
    ,bucket
    ,COUNT(*) AS measure
FROM (
    SELECT uid
        ,DATEADD(day, DATEDIFF(day, 0, timefield), 0) AS bucket
    FROM entries
) AS buckets
GROUP BY uid
    ,bucket
ORDER BY uid
    ,bucket

إذا أردت الرسم بشكل ثلاثي الأبعاد، فمن المحتمل أن أحدد طريقة لترتيب المستخدمين وفقًا لبعض المقاييس الشاملة ذات المعنى بالنسبة للمستخدم.

@ميشال

لأي سبب من الأسباب، المثال الخاص بك يعمل فقط عندما يستخدم @recnum عامل التشغيل أقل من.أعتقد أنه عندما يتم تصفية صف ما، لا تتم زيادة عدد الصفوف، ولا يمكن أن يتطابق مع أي شيء آخر.

إذا كان الجدول الأصلي يحتوي على عمود معرف متزايد تلقائيًا، وتم إدراج الصفوف بترتيب زمني، فيجب أن يعمل هذا:

select timefield from entries
where uid = ? and id % 150 = 0 order by timefield;

بالطبع لن ينجح هذا إذا لم يكن هناك ارتباط بين المعرف والمجال الزمني، إلا إذا كنت لا تهتم فعليًا بالحصول على حقول زمنية متباعدة بشكل متساوٍ، فقط 20 حقلًا عشوائيًا.

هل تهتم حقًا بنقاط البيانات الفردية؟أم أن استخدام وظائف التجميع الإحصائي في رقم اليوم يكفي لإخبارك بما تريد معرفته؟

select timefield
from entries
where rand() = .01 --will return 1% of rows adjust as needed.

لست خبيرًا في MySQL لذا لست متأكدًا من كيفية عمل rand() في هذه البيئة.

كمرجع لي - ولأولئك الذين يستخدمون postgres - سيكون Postgres 9.4 قد طلب مجموعات مجمّعة من شأنها أن تحل هذه المشكلة:

SELECT percentile_disc(0.95) 
WITHIN GROUP (ORDER BY response_time) 
FROM pageviews;

مصدر: http://www.craigkerstiens.com/2014/02/02/Examining-PostgreSQL-9.4/

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top