I'm not running v9, but here's the query in v10.
SELECT workflow.ResourceName AS WorkflowName,
workflowconstruct.ResourceName AS ScheduleName
FROM workflowitemconstructs workflowitem
LEFT OUTER JOIN automateconstructs workflow ON workflowitem.WorkflowID = workflow.ResourceID
LEFT OUTER JOIN automateconstructs workflowconstruct ON workflowitem.ConstructID = workflowconstruct.ResourceID
WHERE TriggerType = 3
ORDER BY workflow.ResourceName,workflowconstruct.ResourceName
You only need the scheduletriggerconstructs table if you want to know details about each schedule. If you're just looking to see which schedules are assigned to which workflows, you only need workflowitemconstructs and automateconstructs. workflowitemconstructs defines which items are used in each workflow, and automateconstructs is used to get the names of those objects as well as the name of the workflow.
Since you're looking for unused repository objects, you can easily query for that directly. Here's the query I use that will return all unused tasks/processes/conditions:
SELECT ResourceName AS ItemName,
CASE ResourceType
WHEN 2 THEN 'Task'
WHEN 4 THEN 'Condition'
WHEN 40 THEN 'Process'
END AS ItemType
FROM automateconstructs
WHERE ResourceType IN (2,4,40)
AND ResourceID NOT IN (SELECT DISTINCT ConstructID FROM workflowitemconstructs WHERE ConstructID<>'' AND ConstructID IS NOT NULL)
ORDER BY ResourceType,ResourceName