SQL Server - Query Joins using Case or IsNull

时间:2015-09-01 22:51:16

标签: sql sql-server case isnull

I had a scenario which I need to write a query.

I had a Query1 which return hundreds of records with these four column names (batch_no, batch_name, class_no, class_name) based on some joins. I need to write a final query (Query2) to return columns from other tables which uses class_no and batch_no column values returned by Query1.

My final query (query2) should return these columns for the all records returned by the query1:

Batch_global_Id (in table global_details), 
batch_no, batch_name, class_no, class_name, 
Start_year, End_year (from table time_details)

Global_details has class_no column so that we can join the results of query1 with Global_details to get the values for the column Batch_global_Id in the final query (Query2).

But the problem here is to get the Start_year and End_year values from the table time_details. We need get the two field values for all the records return by query1 based on class_no, batch_no.

Here is the condition to get those values (Start_year, End_year).

  • If there is a record in time_details table with that class_no, we need to get Start_year and End_year from that record in the final output query.

  • If there is no record in time_details table with that class_no, then get the Start_year and End_year values from the record with matching batch_no in the time_details table.

  • If neither exists (NO record in time_details table with the matching class_no & batch_no), then get the Start_year and End_year values from the record in time_details with batch_no = null

Can some one help me in writing this query?

Edit as per comment

Select 
    batch_no, batch_name, class_no, class_name 
into 
    #temptable 
from 
    ... (query1) ...

Expected query

Select 
    gd.Batch_global_Id, 
    tt.batch_no, tt.batch_name, tt.class_no, tt.class_name, 
    td.Start_year, td.End_year 
from 
    Global_details gd 
inner join 
    time_details td on gd.class_no = td.class_no 
inner join 
    **something like to get values from time_details table based on the above condition//**

2 个答案:

答案 0 :(得分:0)

没有样本数据很难具体,但这应该让你走上正轨。根据表的大小,首先选择start_yearend_year其中batch_no is null为变量可能会更快,然后在合并结束时插入这些变量,而不是添加最后一次加入。

Select a.batch_no, a.batch_name, a.class_no, a.class_name
    , b.Batch_global_Id 
    , coalesce(c.Start_year, d.Start_year, e.Start_year) as StartYear
    , coalesce(c.End_year, d.End_year, e.End_year) as EndYear
from [Query1Results] a
left join Global_details b
on a.class_no = b.class_no
left join time_details c
on a.class_no = c.class_no
left join time_details d
on a.batch_no = d.batch_no
left join time_details e
on e.batch_no is null

答案 1 :(得分:0)

请试试这个

Select 
    gd.Batch_global_Id, 
    tt.batch_no, tt.batch_name, tt.class_no, tt.class_name, 
    td.Start_year, td.End_year 
from 
    Global_details gd, time_details td, temp_table tt
where tt.class_no = gd.class_no
and tt.class_no = td.class_no

union

Select 
    gd.Batch_global_Id, 
    tt.batch_no, tt.batch_name, tt.class_no, tt.class_name, 
    td.Start_year, td.End_year 
from 
    Global_details gd, time_details td, temp_table tt
where tt.class_no = gd.class_no
and tt.batch_no = td.batch_no
and tt.class_no not in (Select tt.class_no from 
    Global_details gd, time_details td, temp_table tt
where tt.class_no = gd.class_no
and tt.class_no = td.class_no)

union 

Select 
    gd.Batch_global_Id, 
    tt.batch_no, tt.batch_name, tt.class_no, tt.class_name, 
    td.Start_year, td.End_year 
from 
    Global_details gd, time_details td, temp_table tt
where tt.class_no = gd.class_no
and td.batch_no is null
and tt.batch_no not in (Select td.batch_no 
from 
    Global_details gd, time_details td, temp_table tt
where tt.class_no = gd.class_no
and tt.batch_no = td.batch_no
and tt.class_no not in (Select tt.class_no from 
    Global_details gd, time_details td, temp_table tt
where tt.class_no = gd.class_no
and tt.class_no = td.class_no))

这是我的逻辑

我根据您的要求将查询分为三部分

第一个查询给出带有class_no条件的结果

第二个查询给出batch_no条件并排除来自第一个查询的记录

与batch_no nu条件的第三个查询相同,并排除来自第二个查询的记录。

如果您能提供数据,那么测试会更好。

我知道当您的记录更多时,这会导致性能问题,但您现在可以尝试这样做。