更新记录SQL?

时间:2016-12-23 16:59:23

标签: sql-server sql-update

首先,当我开始这个项目似乎很简单。表1中的两个表,字段tbl1_USERMASTERID应该从字段tbl2_USERMASTERID表2更新。在我深入研究表2之后,没有唯一的ID可以用作连接这两个表的键。只有匹配表1和表2中记录的方法基于FIRST_NAME,LAST_NAME和DOB。所以我必须在表1中找到记录:

tbl1_FIRST_NAME equals tbl2_FIRST_NAME
AND
tbl1_LAST_NAME equals tbl2_LAST_NAME
AND
tbl1_DOB equals tbl2_DOB

然后更新USERMASTERID字段。我担心这会导致一些重复,一些用户最终会得到不属于他们的USERMASTERID。因此,如果我根据第一个,姓氏和dob找到多个记录,那么这些记录将不会更新。我想跳过并留空。这样我就不会填充无效的USERMASTERID。我不确定解决这个问题的最佳方法是什么,我应该使用SQL还是ColdFusion(我的服务器端语言)?另外如何检测多个匹配记录?

这是我到目前为止所做的:

UPDATE Table1 AS tbl1
LEFT OUTER JOIN Table2 AS tbl2
  ON tbl1.dob = tbl2.dob
  AND tbl1.fname = tbl2.fname
  AND tbl1.lname = tbl2.lname
SET tbl1.usermasterid = tbl2.usermasterid
WHERE LTRIM(RTRIM(tbl1.usermasterid)) = ''

以下是我尝试检测重复项的查询:

SELECT DISTINCT
    tbl1.FName,
    tbl1.LName,
    tbl1.dob,
    COUNT(*) AS count
FROM Table1 AS tbl1
    LEFT OUTER JOIN Table2 AS tbl2
        ON tbl1.dob = tbl2.dob
        AND tbl1.FName = tbl2.first
        AND tbl1.LName = tbl2.last
WHERE LTRIM(RTRIM(tbl1.usermasterid)) = ''
    AND LTRIM(RTRIM(tbl1.first)) <> ''
    AND LTRIM(RTRIM(tbl1.last)) <> ''
    AND LTRIM(RTRIM(tbl1.dob)) <> ''
GROUP BY tbl1.FName,tbl1.LName,tbl1.dob

我测试上面的查询后的一些数据:

First   Last       DOB    Count  
John    Cook    2008-07-11  2
Kate    Witt    2013-06-05  1
Deb     Ruis    2016-01-22  1
Mike    Bennet  2007-01-15  1
Kristy  Cruz    1997-10-20  1
Colin   Jones   2011-10-13  1
Kevin   Smith   2010-02-24  1
Corey   Bruce   2008-04-11  1
Shawn   Maiers  2016-08-28  1
Alenn  Fitchner 1998-05-17  1

如果有人知道如何阻止/跳过更新重复记录或如何改进此查询,请告诉我们。谢谢。

3 个答案:

答案 0 :(得分:1)

您可以使用with common_table_expression (Transact-SQL)检查并避免重复匹配 以及row_number()。,像这样:

with cte as (
select
    t.fname
  , t.lname
  , t.dob
  , t.usermasterid
  , NewUserMasterId = t2.usermasterid
  , rn = row_number() over (partition by t.fname, t.lname, t.dob order by t2.usermasterid)
  from table1 as t
    inner join table2 as t2 on t.dob = t2.dob
      and t.fname = t2.fname
      and t.lname = t2.lname
      and ltrim(rtrim(t.usermasterid)) = ''
  )

--/* confirm these are the rows you want updated 
select * 
  from cte as t
  where t.NewUserMasterId != ''
    and not exists (
      select 1 
        from cte as i 
        where t.dob = i.dob
          and t.fname = i.fname
          and t.lname = i.lname
          and i.rn>1
      );
--*/

/* update those where only 1 usermasterid matches this record
update t
  set t.usermasterid = t.NewUserMasterId
  from cte as t
  where t.NewUserMasterId != ''
      and not exists (
      select 1 
        from cte as i 
        where t.dob = i.dob
          and t.fname = i.fname
          and t.lname = i.lname
          and i.rn>1
    );
--*/

我使用cte提取子查询以提高可读性。根据文档,公共表表达式(cte):

  

指定临时命名结果集,称为公用表表达式(CTE)。这是从简单查询派生而来,并在单个SELECT,INSERT,UPDATE或DELETE语句的执行范围内定义。

使用row_number()为每行分配一个号码,从t.fname, t.lname, t.dob的每个分区开始为1。拥有那些编号允许我们使用not exists() <{1}}子句检查是否存在重复项{/ 1}}

答案 1 :(得分:0)

在加入之前,您可以使用CTE过滤掉Table1中的重复项:

Hospital hospital1 = daoSession1.getHospitalDao().loadByRowId(1);
hospital1.getPatients();

Gson gson = new Gson();
Log.e("msg", gson.toJson(hospital1));

如果表1中没有完全相同的重复项(相同的人口统计信息和相同的ID),这将有效。如果存在完全重复,它们也将从连接中排除,但您可以在CTE之前将其过滤掉以避免这种情况。

答案 2 :(得分:0)

请尝试以下SQL:

ssh_server