database-study-0.0.1: src/Example/RelationalAlgebra.hs
{- |
some queries implemented using operations from relational algebra
-}
module Example.RelationalAlgebra where
import Query
import Company
import qualified Data.Map as Map
import Data.Maybe (isNothing, )
import qualified Data.Tree as Tree
{- |
all employees
-}
employees :: [Emp]
employees = emp
{- |
all clerks
-}
clerks :: [Emp]
clerks =
filter (\e -> job e == Clerk) emp
{- |
all clerks with salary at least 1000
-}
richClerks :: [Emp]
richClerks =
filter (\e -> job e == Clerk && sal e >= 1000) emp
{- |
all employees in research department
-}
researchers :: [Emp]
researchers =
map fst
(filter (\(e,d) -> deptno e == deptno d && dname d == "RESEARCH")
(cross emp dept))
researchers0 :: [Emp]
researchers0 =
map snd
(filter (\(d,e) -> deptno e == deptno d)
(cross (filter (\d -> dname d == "RESEARCH") dept) emp))
hierarchy :: Tree.Forest Emp
hierarchy =
let emptrees =
map (\e -> Tree.Node e (filter ((Just (empno e) ==) . mgr . Tree.rootLabel) emptrees)) emp
in filter (isNothing . mgr . Tree.rootLabel) emptrees
{-
putStr $ Tree.drawForest $ map (fmap ename) hierarchy
-}
hierarchyFast :: Tree.Forest Emp
hierarchyFast =
let emptrees =
Map.fromListWith (++) $
map
(\e -> (mgr e, [Tree.Node e (Map.findWithDefault [] (Just (empno e)) emptrees)]))
emp
in Map.findWithDefault [] Nothing emptrees
{- |
A recursive query:
Compute the total salary for each manager
and the total set of employees he conducts.
-}
teamSalaries :: [(String, Int)]
teamSalaries =
let recurse (Tree.Node e sub0) =
let sub1 = map recurse sub0
in Tree.Node (ename e, sal e + sum (map (snd . Tree.rootLabel) sub1)) sub1
in Tree.flatten =<< map recurse hierarchyFast