在不相等的列上连接两个表

时间:2019-11-03 13:30:30

标签: sql sql-server join

我有一个要加入的设备表和一个停机时间表,我想显示所有设备和停机时间。如果某台设备没有停机时间,那么我想在值为null的行中显示零。这就是我下面的内容。它只给我其他表中有停机时间的设备。

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 

我要完成的工作的示例。但是停机时间表捕获了变化的数据,因此该设备整个月可能没有任何停机时间。 设备总数66件 设备/停机时间 1717 57
1723 0 1724 0 1725 50 1728 0 1734 35 1738 0

3 个答案:

答案 0 :(得分:1)

最终答案

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

提琴:https://dbfiddle.uk/?rdbms=sqlserver_2012&fiddle=cc2c2cce139cda7d7c5878d6c967da34

一步一步

第1步:

您需要做的是使用外部联接,以及一个将NULL替换为零的函数(即您正在执行的操作)。

因此,第一步,请执行以下操作:

Select b.EquipNbr, ISNULL((a.Downtime),0) From MobileDowntime (nolock) a
RIGHT OUTER Join MblEquip (nolock) b on a.EquipNbr = b.EquipNbr

第2步:使用分组依据

下面,您可以添加分组依据以获取以下内容:

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

最后一部分是使用日期的where条件。

更新

我认为转换错误是由于数值比较!=造成的。 我做了一个实验,将Varchar转换为Int。

然后我将!=更改为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

答案 1 :(得分:1)

您需要一个left join并将MobileDowntime表上的条件移至on子句:

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;

请注意,我替换了您的表别名(希望正确)。 ab毫无意义。相反,我为表名使用了缩写。

答案 2 :(得分:0)

您可以使用左外部联接,在没有停机时间的情况下它将显示为空