合并where子句删除太多行

时间:2017-04-20 09:10:37

标签: sql coalesce

我有两个表,每个表都包含相同的字段,但是来自两个不同的数据输入系统,我使用UNION加入,所以没有真正的重复记录。然而,在两个系统上输入的数据略有不同,我需要在一个系统上删除输入的行,在一个系统上输入空值但在另一个系统上输入值 - 我使用了COALESCE,在99%的情况下使用了这个工作得很好。问题是有两行都有真正的空值(见下面的示例数据):

PersonID    Location1   Location2           Date
1           NULL            NULL            2016-05-01
1           NULL            NULL            2014-10-01
1           Home            Home            2016-05-01

2           HospitalA       HospitalB       2016-07-23
2           NULL            NULL            2016-07-23

3           HospitalA       HospitalA       2014-12-19
3           HospitalB       HospitalB       2016-08-16

如果日期相同,我只想要具有位置值的行,但如果日期不同,我希望每个日期有一行,即使其中一个日期的位置为NULL - PersonID 1有两行,一行2014-10-01的空位置和2016-05-01的位置; PersonID 2有一行的位置日期为2016-07-23,PersonID 3有两行,包含位置和不同的日期。

我正在使用的查询是

select *
from 
(select PersonID, Location1, Location2, Date
from tablea
union
select PersonID, Location1, Location2, Date
from tableb) as PID
where Location1 = coalesce(Location1,'')

提前感谢任何指针

3 个答案:

答案 0 :(得分:1)

问题是UNION一个接一个地列出了两个表的内容,因此每一行只有原始表的字段。这意味着where Location1 = coalesce(Location1,'')正在检查字段,而不是自己。

要实现您的目标,您可能需要对UNION

的结果进行汇总
select  PersonID, max(Location1), max(Location2), Date
from    (
          select  PersonID, Location1, Location2, Date
          from    tablea
          union all
          select  PersonID, Location1, Location2, Date
          from tableb
        ) as PID
group by PersonID, Date

答案 1 :(得分:0)

看起来你想在GROUP BY中使用COALESCE作为聚合运算符:

SELECT PersonID,Date,COALESCE(location1),COALESCE(location2)   来自你的工会 - 在这里 GROUP BY PersonID,日期

但是,我不知道SQL是否支持这种聚合函数形式的COALESCE。

即使它确实有效,你仍然需要仔细检查如果某个人在同一天有两个不同的位置会发生什么(COALESCE必须只保留其中一个)。

答案 2 :(得分:0)

每人一行,日期转换为SQL中的GROUP BY person, date

select 
  personid, 
  max(location1) as location1,
  max(location2) as location2,
  date
from 
(
  select personid, location1, location2, date
  from tablea
  union all
  select personid, location1, location2, date
  from tableb
) as pid
group by personid, date;