Question : Full Outer Join for CR

Hi Experts,

I'm trying to get data from 2 tables that have no 1 to 1 relationship except for the column - job_no. The following statement retrieves very limited data or none at all in some columns:

SELECT job_history.job_no, job_history.cost, job_history.cost_code_no, job_history.cost_class_no, job_budgets.job_no, job_budgets.orig_est_dollars, job_budgets.cost_code_no, job_budgets.cost_class_no

FROM job_budgets

FULL OUTER JOIN job_history
ON job_budgets .job_no = job_history.job_no

The linking column "job_no" contains many separate rows for each unique job_no number - they contain periodic job cost data entered over time and I can't help but think that this is causing some of my problem - but I am a real novice in SQL.

The column job_budgets.orig_est_dollars contains budgeted costs for a construction project.
The column job_history.cost contains the actual costs for a project. These costs (in both tables) are broken down by categories (1 - 26) in the column: cost_code_no (in both tables)  and classified as material, labor, or sub by the numeric content of the column cost_class_no (1,2,3). I need to break out these categories in my report to compare actual costs to budgeted costs. I simply need a query that will pull all of the data from these two tables in these columns so I can run reports on it.

Answer : Full Outer Join for CR

You could, but honestly I prefer to do as much data prep as possible back on the server. That way I can manipulate sometimes without having to re-write reports, and try to take control over the volume of data being bandied about, and, trying to take advantage of anything the Server might be able to offer in terms of performance.

In this case, I would probably create a view and then simply select from the view.

A view is like a virtual table. It is really more like a stored query, with the advantage that you can refer to a view just like any other table. It doesnt hold data itelf, but knows where to get it from, and the Server does too so will try to use all the performance stats from the underlying tales when looking at query plans.

Creating the view is a once off process, once there, use it just like a table. Any updates to data is done on the actual tables, and is instantaneously reflected in the view. They are pretty cool things and ideally suited to these types of cases where the query is a bit involved / a bit unwieldy to use directly.

First time in, you "create" the view, subsequent changes are done using "alter"

-- OK, lets create the view.... naming conventions can be important and it is not uncommon to find the few few characters reflecting the type of database object.
-- In this case, using the prefix VW to denote VIEW

CREATE VIEW vw_Jobs_Budget_vs_Actual AS
SELECT    job_no
          , cost_code_no
          , sum(Labor_Budget) as labor_budget
          , sum(Material_Budget) Material_Budget
          , sum(Subcontract_Budget) Subcontract_Budget
          , sum(Mileage_Budget) Mileage_Budget
          , sum(Burden_Budget) Burden_Budget
          , sum(Labor_cost) Labor_cost
          , sum(Material_cost) Material_cost
          , sum(Subcontract_cost) Subcontract_cost
          , sum(Mileage_cost) Mileage_cost
          , sum(Burden_cost) Burden_cost
          , sum(total_budget) as total_budget
          , sum(total_cost) as total_cost
          , sum(total_budget) - sum(total_cost) as variance

FROM   (
            select  job_no
                      , cost_code_no
                      , case when cost_class_no = 1 then orig_est_dollars else 0 end as Labor_Budget
                      , case when cost_class_no = 2 then orig_est_dollars else 0 end as Material_Budget
                      , case when cost_class_no = 3 then orig_est_dollars else 0 end as Subcontract_Budget
                      , case when cost_class_no = 4 then orig_est_dollars else 0 end as Mileage_Budget
                      , case when cost_class_no = 6 then orig_est_dollars else 0 end as Burden_Budget
                      , orig_est_dollars as total_budget
                      , 0.00 as Labor_cost
                      , 0.00 as Material_cost
                      , 0.00 as Subcontract_cost
                      , 0.00 as Mileage_cost
                      , 0.00 as Burden_cost
                      , 0.00 as total_cost
            From  Job_Budgets

            UNION ALL

            select  job_no
                    , cost_code_no
                    , 0.00 as Labor_budget
                    , 0.00 as Material_budget
                    , 0.00 as Subcontract_budget
                    , 0.00 as Mileage_budget
                    , 0.00 as Burden_budget
                    , 0.00 as total_budget
                    , case when cost_class_no = 1 then cost else 0 end  as Labor_Cost
                    , case when cost_class_no = 2 then cost else 0 end as Material_Cost
                    , case when cost_class_no = 3 then cost else 0 end as Subcontract_Cost
                    , case when cost_class_no = 4 then cost else 0 end as Mileage_Cost
                    , case when cost_class_no = 6 then cost else 0 end as Burden_Cost
                    , cost as total_cost
                     
            From  Job_History
          ) src
GROUP BY    Job_No, cost_code_no
-- ORDER BY    Job_No, cost_code_no
-- dont include ORDER BY in a view unless you also use the TOP qualifier
-- just remember to do your own order by when selecting from the view.
GO

-- Now that has been done...
-- We can start using it. Referring to it just like any other table (pretty much... we can select, join, use where, use order by, aggregate etc etc)

select * from vw_Jobs_Budget_vs_Actual

-- and that is what you now use in your crystal reports as your data source...


Random Solutions  
 
programming4us programming4us