سؤال

يوم جيد كل.

لديّ هذه البيئة: على mysql db ، في كل مرة يقوم المستخدم بتسجيل الدخول على موقع ، يتم إنشاء صف جديد باسمه ، والوقت الذي يقوم عليه تسجيل الدخول إليه. نظرًا لأن النظام حصري متبادل ، فسيكون هناك مستخدم فقط في وقت معين ، وإذا وصل مستخدم جديد ، يتم تسجيل تسجيل الدخول.

الآن طلبوا مني حساب إجمالي الوقت لجميع المستخدمين على النظام ، لذلك في الأساس ، يجب أن أقوم بتجميع الاختلافات في الوقت المناسب من تسجيل الدخول والخارق التالي.

user  |       timestamp     |
------------------------------
alpha | 2013-01-19 03:14:07
beta  | 2013-01-20 11:24:04
alpha | 2013-01-21 02:11:37
alpha | 2013-01-21 03:10:31    <---- a user could login twice, it is normal
gamma | 2013-01-21 11:24:04
beta  | 2013-01-21 11:25:00

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

هل هناك طريقة لحسابها عن طريق الاستعلام؟ أو من الأفضل إضافة عمود "Time Online" والسماح لـ Sistem بحساب في كل مرة يقوم فيها المستخدم بتسجيل الدخول كم من الوقت الذي يقضيه عبر الإنترنت؟

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

المحلول

هذا يتطلب التواصل الذاتي إذا كنت تريد القيام بذلك في MySQL. إنه لألم في الرقبة القيام بالضغط ذاتيًا لأن MySQL ليس له وظيفة Rownum. لكنها لا تزال قابلة للتنفيذ.

أولاً ، نحتاج إلى إنشاء مسافة فرعية لإنشاء جدول افتراضي يحاكي SELECT rownum, user, timestamp FROM login الذي يمكننا أن نفعل مثل هذا. http://sqlfiddle.com/#!2/bf6ef/2/0

SELECT @a:=@a+1 AS rownum, user, timestamp
    FROM (
        SELECT user, timestamp
          FROM login
         ORDER BY timestamp
    ) C,
    (SELECT @a:=0) s

بعد ذلك ، نحتاج إلى القيام بالانضمام الذاتي لهذا الجدول الافتراضي إلى نسخة من نفسها. ما نريده في مجموعة النتائج هذه هو قائمة بجميع أزواج الصفوف المتتالية في الجدول. هذا الاستعلام هو كرة شعر - يضع منظم في لغة الاستعلام الهيكلية. ولكنه يعمل. ها هو: http://sqlfiddle.com/#!2/bf6ef/4/0

SELECT first.user AS fuser, 
       first.timestamp AS ftimestamp,
       second.user AS suser,
       second.timestamp as stimestamp,
       TIMESTAMPDIFF(SECOND, first.timestamp, second.timestamp) AS timeloggedin

  FROM (
       SELECT @a:=@a+1 AS rownum, user, timestamp
         FROM (
             SELECT user, timestamp
               FROM login
           ORDER BY timestamp
              ) C,
          (SELECT @a:=0) s
        ) AS first
  JOIN (
       SELECT @b:=@b+1 AS rownum, user, timestamp
         FROM (
             SELECT user, timestamp
               FROM login
           ORDER BY timestamp
              ) C,
          (SELECT @b:=0) s
        ) AS second ON first.rownum+1 = second.rownum

الخدعة الكاملة لمقارنة الصفوف المتتالية هي

SELECT (virtual_table) AS first
  JOIN (virtual_table) AS second ON first.rownum+1 = second.rownum

نمط الاستعلام. Rownum+1 = Rownum شيء يجمع الصفوف بأرقام صف متتالية معًا.

بعد ذلك ، نحتاج إلى تلخيص نتيجة هذا الاستعلام للحصول على إجمالي الوقت المسجل لكل مستخدم. سوف يعمل مثل هذا:

  SELECT user, SUM(timeloggedin) AS timeloggedin
    FROM (
          /* the self-joined query */
         ) AS selfjoin
   GROUP BY user
   ORDER BY user

هذا يبدو هكذا: http://sqlfiddle.com/#!2/bf6ef/5/0

هذا هو الاستعلام كله وضعت معا.

SELECT user, SUM(timeloggedin) AS timeloggedin
  FROM (
      SELECT first.user AS user, 
             TIMESTAMPDIFF(SECOND, first.timestamp, second.timestamp) AS timeloggedin
        FROM (
             SELECT @a:=@a+1 AS rownum, user, timestamp
         FROM (
                   SELECT user, timestamp
                     FROM login
                 ORDER BY timestamp
                    ) C,
                (SELECT @a:=0) s
              ) AS first
        JOIN (
             SELECT @b:=@b+1 AS rownum, user, timestamp
               FROM (
                   SELECT user, timestamp
                     FROM login
                 ORDER BY timestamp
                    ) C,
                (SELECT @b:=0) s
              ) AS second ON first.rownum+1 = second.rownum
         ) AS selfjoin
   GROUP BY user
   ORDER BY user

إنه ليس بديهية حقيقية بالنسبة لشخص يستخدم في التفكير الإجرائي والخوارزمية. ولكن هذه هي الطريقة التي تفعل بها هذا النوع من المقارنة المتتالية في الصفوف في SQL.

نصائح أخرى

جرب مع هذا ... أقل أو أكثر هو حل مشكلتك ...

    CREATE TABLE `matteo` (
      `user` varchar(20) DEFAULT NULL,
      `timestamp` int(11) DEFAULT NULL
    ) ENGINE=InnoDB DEFAULT CHARSET=latin1;

    INSERT INTO matteo(user, `timestamp`) VALUES ('alpha', 7);
    INSERT INTO matteo(user, `timestamp`) VALUES ('beta', 9);
    INSERT INTO matteo(user, `timestamp`) VALUES ('alpha', 17);
    INSERT INTO matteo(user, `timestamp`) VALUES ('alpha', 27);
    INSERT INTO matteo(user, `timestamp`) VALUES ('gamma', 77);
    INSERT INTO matteo(user, `timestamp`) VALUES ('beta', 97);

    select a.*,b.*,b.`timestamp`-a.`timestamp` as delta
    from
    (SELECT @rownum := @rownum + 1 AS id,t.*
          FROM matteo t,(SELECT @rownum := 0) r) a
    join
    (SELECT @rownum2 := @rownum2 + 1 AS id,t.*
          FROM matteo t,(SELECT @rownum2 := 0) r) b 
    where a.id=b.id-1

:-) أراك الاثنين !!!

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