-- | TPC-H Query Q16
q16 :: Text -> Text -> [Integer] -> Q [((Text, Text, Integer), Integer)]
q16 brand typ sizes = sortWith byDescCount
      $ groupAggr fst snd (length . nub)
      [ tup2 (tup3 (p_brandQ p) (p_typeQ p) (p_sizeQ p)) (ps_suppkeyQ ps)
      | ps <- partsupps
      , p  <- parts
      , p_partkeyQ p == ps_partkeyQ ps
      , p_brandQ p /= toQ brand
      , not (p_typeQ p `like` toQ typ)
      , p_sizeQ p `elem` toQ sizes
      , not (ps_suppkeyQ ps `elem` [ s_suppkeyQ s
                                   | s <- suppliers
                                   , s_commentQ s `like` "%Customer%Complaints%"
                                   ])
      ]
q16 :: Text -> Text -> [Integer] -> Q [((Text, Text, Integer), Integer)]
q16 brand typ sizes = sortWith byDescCount
      $ groupAggr fst snd (length . nub)
      [ tup2 (tup3 (p_brandQ p) (p_typeQ p) (p_sizeQ p)) (ps_suppkeyQ ps)
      | ps <- partsupps
      , p  <- parts
      , p_partkeyQ p == ps_partkeyQ ps
      , p_brandQ p /= toQ brand
      , not (p_typeQ p `like` toQ typ)
      , p_sizeQ p `elem` toQ sizes
      , not (ps_suppkeyQ ps `elem` [ s_suppkeyQ s
                                   | s <- suppliers
                                   , s_commentQ s `like` "%Customer%Complaints%"
                                   ])
      ]
q16 brand typ sizes = sortWith byDescCount
      $ groupAggr fst snd (length . nub)
      [ tup2 (tup3 (p_brandQ p) (p_typeQ p) (p_sizeQ p)) (ps_suppkeyQ ps)
      | ps <- partsupps
      , p  <- parts
      , p_partkeyQ p == ps_partkeyQ ps
      , p_brandQ p /= toQ brand
      , not (p_typeQ p `like` toQ typ)
      , p_sizeQ p `elem` toQ sizes
      , not (ps_suppkeyQ ps `elem` [ s_suppkeyQ s
                                   | s <- suppliers
                                   , s_commentQ s `like` "%Customer%Complaints%"
                                   ])
      ]