Reputation: 41
I have a equipment table and a downtime table that I am wanting to join, I am wanting to display all the equipment and the downtime hours. If there is no downtime for a certain piece of equipment then I want to display a zero in the rows where value is null. This is what I have below. It only gives me the equipment that has downtime in the other table.
Select a.EquipNbr,
ISNULL(Sum(a.Downtime),0)
From MobileDowntime (nolock) a
Join MblEquip (nolock) b on a.EquipNbr = b.EquipNbr
Where b.DelFlg = 0 and
b.EquipNbr <> 'Clean Shop' and
a.DateTm Between DATEADD(month, DATEDIFF(month, 0, getDate()), 0) and DATEADD(month, DATEDIFF(month, -1, getDate()), -1)
Group By a.EquipNbr
Order by a.EquipNbr Asc
example of what I am trying to accomplish.. But the downtime table on captures data on change so there might not be any downtime for that piece of equipment for the whole month.
66 total pieces of equipment
Equipment / Downtime
1717 57
1723 0
1724 0
1725 50
1728 0
1734 35
1738 0
Upvotes: 0
Views: 78
Reputation: 25727
Select b.EquipNbr, Sum(ISNULL((a.Downtime),0)) From MobileDowntime (nolock) a
RIGHT OUTER Join MblEquip (nolock) b on a.EquipNbr = b.EquipNbr
Where b.DelFlg = 0 and b.EquipNbr != 'Clean Shop'
AND
(
a.datetm is null or
(a.DateTm Between DATEADD(month, DATEDIFF(month, 0, getDate()), 0)
and DATEADD(month, DATEDIFF(month, -1, getDate()), -1) )
)
Group By b.EquipNbr Order by b.EquipNbr Asc
Fiddle: https://dbfiddle.uk/?rdbms=sqlserver_2012&fiddle=cc2c2cce139cda7d7c5878d6c967da34
Step 1:
What you need to do is to use an outer-join, and a function that replaces NULL with zero (that you are doing).
So as a first step you would do the following:
Select b.EquipNbr, ISNULL((a.Downtime),0) From MobileDowntime (nolock) a
RIGHT OUTER Join MblEquip (nolock) b on a.EquipNbr = b.EquipNbr
Step 2: With Group by
Following, you can add the group by to get the following:
Select b.EquipNbr, Sum(ISNULL((a.Downtime),0)) From MobileDowntime (nolock) a
RIGHT OUTER Join MblEquip (nolock) b on a.EquipNbr = b.EquipNbr
Where b.DelFlg = 0 and b.EquipNbr != 'Clean Shop'
Group By b.EquipNbr Order by b.EquipNbr Asc
The final part is the where condition using the dates.
The conversion error I think was because of the numerical comparison !=
.
I did an experiment and converted the Varchar to Int.
Then I changed the !=
to not like
.
Select b.EquipNbr, Sum(ISNULL((a.Downtime),0)) From MobileDowntime (nolock) a
RIGHT OUTER Join MblEquip (nolock) b on a.EquipNbr = b.EquipNbr
Where b.DelFlg = 0 and b.EquipNbr not like 'Clean Shop'
AND
(
a.datetm is null or
(a.DateTm Between DATEADD(month, DATEDIFF(month, 0, getDate()), 0)
and DATEADD(month, DATEDIFF(month, -1, getDate()), -1) )
)
Group By b.EquipNbr Order by b.EquipNbr Asc
Upvotes: 1
Reputation: 1269503
You want a left join
and to move conditions on the MobileDowntime
table to the on
clause:
Select e.EquipNbr, coalesce(sum(md.Downtime), 0)
From MblEquip e left join
MobileDowntime md
on md.EquipNbr = e.EquipNbr and
md.DateTm between DATEADD(month, DATEDIFF(month, 0, getDate()), 0) and DATEADD(month, DATEDIFF(month, -1, getDate()), -1)
where e.DelFlg = 0 and e.EquipNbr <> 'Clean Shop'
group by e.EquipNbr
order by e.EquipNbr Asc;
Note that I replaced your table aliases (hopefully correctly). a
and b
are meaningless. Instead, I used abbreviations for the table names.
Upvotes: 1
Reputation: 135
You can use left outer join in which it will show null when there is no downtime hours
Upvotes: 0