vendredi 18 septembre 2015

SQLite Mode of grouped values? (and possibly median)

I have a table of personID, categoryID and value. For each person I want to obtain the modal value for each category (highest mode in that category if there is more than one equal modal value) In addition I want to every person to show all possible categories from another table, even if a particular person doesn't have any values recorded for that category.

eg my two tables look like (blank line for clarity)

    TableResults            |   TableCategories
     =======                |     ==========
person  category  value     |         Category
  X       A        1        |           A
  X       A        2        |           B
                            |           C
  X       B        4        |       
  X       B        2        |
  X       B        4        |
  X       B        4        |
  X       B        2        |
  X       B        2        |
  X       B        3        |
                            |
  X       C        2        |
  X       C        3        |
                            | 
  Y       A        4        |
  Y       A        3        |
  Y       C        3        |
                            |
  Z       B        2        |
                            |
etc                         | 

Then I want my results to look like

person   Category   ModalValue
  X        A           2          
  X        B           4         <- Values 2 and 4 both occured 3 times so choose 4
  X        C           3

  Y        A           4
  Y        B           0         <- this person has no value available for Category B 
  Y        C           3

  Z        A           0        <- this person has no value available for Category A
  Z        B           2
  Z        C           0        <- or for Category C 

Using ideas from Calculating the mode with SQLite with grouping I came up with the sql below.
see http://ift.tt/1YkjUUG

This appears to almost work (does not show categories when the person has no value for that category) but it also looks very clumsy.

Can anyone suggest a simpler way to do it?

 SELECT   ModalValues.person       ,
          TableCategories.category ,
          ifnull(ModalValues.TheValue,0) AS ModalValue
 FROM     TableCategories
          LEFT JOIN
                   ( SELECT  person  ,
                            category ,
                            TheValue ,
                            MAX(GroupsTable.LevelCount) AS MaxCount
                   FROM     ( SELECT  person  ,
                                     category ,
                                     TheValue ,
                                     LevelCount
                            FROM     ( SELECT  person  ,
                                              category ,
                                              TheValue ,
                                              COUNT(TheValue) AS LevelCount
                                     FROM     TableResults
                                     GROUP BY person ,
                                              category
                                     ) AS CountsTable
                            GROUP BY person  ,
                                     category,
                                     TheValue
                            ) AS GroupsTable
                   GROUP BY person,
                            category
                   ) AS ModalValues
          ON       TableCategories.category = ModalValues.category
 ORDER BY ModalValues.person,
          TableCategories.category

Also, I've looked at the links below but have had no success at writing similar code to the above but getting the median instead of the mode (I won't post the code I am trying to save space)

How can I calculate the median of values in SQLite?

median in SQLITE on group

SQL ranking query to compute ranks and median in sub groups

If anyone can help with making code similar to the above but getting the median instead of the mode I'd be very grateful

Aucun commentaire:

Enregistrer un commentaire