我们最近遇到了一些问题,其中从表中删除重复条目的sql脚本不会使用最新的条目作为要保留的条目。我认为这一行是问题
delete from vaccine_patient_details
where vacc_pat_guid <>
(Select top 1 vacc_pat_guid
from vaccine_patient_details as v
where v.patient_guid = patient_guid and
v.vaccine_guid = vaccine_guid
order by date_given desc)
这是正确的语法吗?我发现另一个版本的脚本在另一个表上工作。 (名称已更改为与第一个示例匹配)
delete from vaccine_patient_details
where vacc_pat_guid <>
(Select top 1 vacc_pat_guid
from vaccine_patient_details as v
where v.patient_guid = vaccine_patient_details.patient_guid and
v.vaccine_guid = vaccine_patient_details.vaccine_guid
order by date_given desc)
这个使用内部where子句中已删除表的表名,是否会导致我的第一个版本出现问题?
有关表的详细信息:
答案 0 :(得分:3)
第一个表上没有任何别名,查询等同于:
delete from vaccine_patient_details
where vacc_pat_guid <>
(Select top 1 vacc_pat_guid
from vaccine_patient_details as v
where v.patient_guid = v.patient_guid and
v.vaccine_guid = v.vaccine_guid
order by date_given desc)
一个好的将是
delete v1 from vaccine_patient_details as v1
where v1.vacc_pat_guid <>
(Select top 1 v.vacc_pat_guid
from vaccine_patient_details as v
where v.patient_guid = v1.patient_guid and
v.vaccine_guid = v1.vaccine_guid
order by v.date_given desc)
通过在您向我们展示的第二个查询中指定表名,优化器明白他必须加入第一个表,因为seconde表名为'v',第一个是'vaccine_patient_details',并且他不要混淆。
他在第一个中感到困惑,因为他不知道patient_guid是第一个表格还是第二个表格中的字段。所以它越接近,所以第二个。
编辑:
来自http://dev.mysql.com/doc/refman/5.0/en/delete.html
如果声明表的别名, 你在引用时必须使用别名 到桌子:
DELETE t1 FROM test AS t1, test2 WHERE
...
答案 1 :(得分:1)
您的代码的相关部分(如您所述)此...
where v.patient_guid = patient_guid and
v.vaccine_guid = vaccine_guid
等于运算符的右侧没有指定表。优化器将首先检查最本地范围的匹配表。在这种情况下,子查询中的表具有那些字段,优化后甚至不检查外部查询中的表。
代码的第二个版本明确指出要引用哪个表,这恰好是外部查询中的表。
所以,简而言之,是的;问题是第一个版本隐式引用了内部查询的表实例,它应该显式引用外部查询的表实例。
注意:我不同意这种自我加入是一个问题。
答案 2 :(得分:1)
delete a from vaccine_patient_details a, vaccine_patient_details b
where a.patient_guid = b.patient_guid
and a.vaccine_guid = b.vaccine_guid
and a.date_given < b.date_given
答案 3 :(得分:0)
加入同一张表是否合法,这不是一个好主意。您最好将您认为应该删除的记录的ID提取到一个单独的表中(然后您可以验证它们是否正确),并使用它们来运行删除。
我认为尝试根据这样的复杂查询进行删除会在某些时候遇到麻烦。
答案 4 :(得分:0)
尝试一下(当然在你的开发环境中)
delete vaccine_patient_details
from vaccine_patient_details V
where vacc_pat_guid <>
(Select top 1 vacc_pat_guid
from vaccine_patient_details
where V.patient_guid = patient_guid and
V.vaccine_guid = vaccine_guid
order by date_given desc)