0

after doing some joins I got a non-grouped result/view like:

id | from                | to                  | who    | group | ...
 1 | 2012-01-01 12:00:00 | 2012-01-01 14:00:00 | adam   | sales
 2 | 2012-01-01 12:00:00 | 2012-01-01 15:00:00 | bertil | sales
 2 | 2012-01-01 12:00:00 | 2012-01-01 15:00:00 | bertil | admin
...

the result is going to be grouped by DATE(from)

but I'm also interested in the time-length (UNIX_TIMESTAMP(to) - UNIX_TIMESTAMP(from))/3600 and I want a sum of it grouped by day, but i only want each id to count once

can I do somthing like:
SUM((UNIX_TIMESTAMP(to) - UNIX_TIMESTAMP(from))/3600 DISTINCT id)
or maybe use a variable and a IF()?
or do i have to do a subquery of by big query grouped by id and then the outer query grouped by date?

UPDATE 1 clarify what you expect to see as an answer
the result above is the times people worked, and what groups they was members of, after filtering out the groups that is interesting at the moment, I want to know how much mantime that was spent that day, for the example data: its 2 hours for adam + 3 hours for bertil = 5 hours, but bertil is a member of 2 of the interesting groups, so his time is shown twice

UPDATE 2 provide a little more data
Above was a try to of an generalization of this query

SELECT
   worktimes.date AS 'Datum',
   COUNT(DISTINCT employments.citizen_id) AS 'Säljare',
   SUM(UNIX_TIMESTAMP(TIMESTAMP(worktimes.date, worktimes.death)) - UNIX_TIMESTAMP(TIMESTAMP(worktimes.date, worktimes.birth))) AS 'Mantid',
   COUNT(DISTINCT agreements.agreement_id) AS 'Avtal',
   COUNT(DISTINCT IF(agreement_status.status_id = 57, agreements.agreement_id, NULL)) AS 'Godkända',
   COUNT(DISTINCT IF(agreement_status.status_id = 3, agreements.agreement_id, NULL)) AS 'Ånger',
   COUNT(DISTINCT IF(agreement_status.status_id = 4, agreements.agreement_id, NULL)) AS 'Makuleringar',
   COUNT(DISTINCT IF(agreement_status.status_id IS NULL, agreements.agreement_id, NULL)) AS 'Övrigt'
FROM worktimes
LEFT JOIN employments USING (employment_id)
LEFT JOIN membership_cache ON (
   membership_cache.target_type = 34 AND
   membership_cache.target_id IN (136, 138) AND
   membership_cache.member_type = 11 AND
   membership_cache.member_id = employments.citizen_id AND
   DATE(membership_cache.birth) <= worktimes.date AND
   (membership_cache.death IS NULL OR worktimes.date < DATE(membership_cache.death))
   )
LEFT JOIN agreements ON (
   agreements.citizen_id = employments.citizen_id AND
   agreements.project_id = 20 AND
   agreements.date >= 20110101 AND
   DATE(agreements.date) = worktimes.date
   )
LEFT JOIN agreement_status ON (
   agreements.agreement_id = agreement_status.agreement_id AND
   agreement_status.value = 1 AND
   agreement_status.death IS NULL AND
   agreement_status.status_id IN (3, 4, 57)
   )
WHERE
   worktimes.death IS NOT NULL AND
   membership_cache.member_id IS NOT NULL AND
   worktimes.date >= 20110101
GROUP BY DATE(agreements.date)

mysql EXPLAIN of above query

+----+-------------+------------------+-------+------------------------------------------------------+------------------------+---------+-------------------------------+------+-----------------------------------------------------------+
| id | select_type | table            | type  | possible_keys                                        | key                    | key_len | ref                           | rows | Extra                                                     |
+----+-------------+------------------+-------+------------------------------------------------------+------------------------+---------+-------------------------------+------+-----------------------------------------------------------+
|  1 | SIMPLE      | membership_cache | range | target,member                                        | target                 | 10      | NULL                          |   85 | Using where; Using index; Using temporary; Using filesort |
|  1 | SIMPLE      | employments      | ref   | employment_id,citizen                                | citizen                | 8       | db.membership_cache.member_id |    1 | Using where; Using index                                  |
|  1 | SIMPLE      | worktimes        | ref   | employment,date,death                                | employment             | 8       | db.employments.employment_id  |   34 | Using where                                               |
|  1 | SIMPLE      | agreements       | ref   | project,date,project_customer,agreements_per_citizen | agreements_per_citizen | 8       | db.employments.citizen_id     |   36 |                                                           |
|  1 | SIMPLE      | agreement_status | ref   | agreement,status_birth,status_death                  | agreement              | 8       | db.agreements.agreement_id    |    1 |                                                           |
+----+-------------+------------------+-------+------------------------------------------------------+------------------------+---------+-------------------------------+------+-----------------------------------------------------------+

And the problem is that SUM(UNIX_TIMESTAMP(TIMESTAMP(worktimes.date, worktimes.death)) - UNIX_TIMESTAMP(TIMESTAMP(worktimes.date, worktimes.birth))) AS 'Mantid' is getting multiplied by the number of matching rows in the tables: membership_cache, agreements and agreement_status

4

0 回答 0