Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>As others have suggested, modifying the table structure is a better approach in the long run. Trying to pair up log records (with no matching key) is difficult, and sometimes impossible. A slightly modified structure would be easier to query, and would yield more accurate results. However, if you absolutely cannot modify the table, it might be possible to calculate a <em>rough</em> total - IF your record ID is numeric/sequential. </p> <p>The assumption is a "logout" record is always inserted <em>after</em> a "login". So the logout's record ID would always be greater than that of the corresponding "login". A subquery could convert the login information into pairs: ie current and next login record. The corresponding "logout" record id would fall within that range. Once you have matched up login/logouts, use date/time functions to calculate the time elapsed in minutes. Then SUM() the values and format the results however you wish. Note: Obviously proper indexing of the table is a <strong>must</strong>. </p> <p>That said, this method only provides an estimate. It has several flaws:</p> <ul> <li>Some databases do not optimize subqueries very well. So even with indexes, the query performance can be quite poor if there is a lot of data involved.</li> <li>Relies solely upon the record id for identification. </li> <li>Does not account for stray logout records or erroneous/duplicates. So it may be less accurate than other methods</li> <li>Requires more convoluted sql than alternative structures</li> </ul> <p>Anyway, I am not sure of the MySQL syntax off the top of my head. But ignoring the MS Sql Server specific functions, this should be close. The performance in MS SQL was decent with proper indexes, and about 100K records. </p> <pre><code>SELECT SUM(DateDiff(n, li.LogTime, lo.LogTime)) AS TotalTimeInMinutes FROM ( SELECT li.RecordID, li.UserID, li.LogType, li.LogTime, ( SELECT MIN(t.RecordID) FROM YourTable t WHERE t.UserID = li.UserID AND t.LogType = li.logType AND t.RecordID &gt; li.RecordID ) AS NextRecordID FROM YourTable li WHERE li.UserID = 123 AND li.LogType = 'login' ) li INNER JOIN YourTable lo ON lo.UserID = li.UserID AND lo.LogType = 'logout' AND lo.RecordID BETWEEN li.RecordID AND li.NextRecordID </code></pre>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload