我有两张表per_asg
和xx_asg
,他们有相同的号码。列,理想情况下应该相同没有。数据。
per_asg :
person_id start_date end_date
-------------------------------------------
1 01-jan-2016 07-jan-2016
1 02-feb-2016 08-march-2016
xx_per_asg
person_id start_date end_date
-------------------------------------
1 01-jan-2016 07-jan-2016
1 02-feb-2016 08-march-2016
1 03-feb-2016 04-sep-2016
在xx_per_asg上看到有一个额外的行,包含start_date '03-feb-2016'
和end_date '04-sep-2016'.
我写了一个查询来获取这些行但是我没有得到额外的行completly:
select start_date
from xx_per_asg xx_per_asg, per_asg pa
where xx_per_asg.person_id = pa.person_id
and xx_per_asg.start_date <> pa.start_date
但这仍然是整套数据
答案 0 :(得分:2)
如果你想要额外的行,我希望查询更像这样:
select xx.*
from xx_per_asg xx
where not exists (select 1
from per_asg pa
where pa.person_id = xx.person_id and
pa.start_date = xx.start_date
);
答案 1 :(得分:1)
如果每个表可能有不在另一个表中的行,并且您需要找到这两种类型,那么这样的东西应该有效。假设两个表都没有重复的行(例如,如果每个表都有主键,则为真),那么如果对这两个表执行union all
,则两个表中存在的行将在联合中重复。不在两个表中的那些将不会重复。因此,在union all
之后,我们可以按所有列进行分组,并使用HAVING COUNT(*) = 1
条件查找仅在一个表中但不在另一个表中的行。
对此的一个小调整也会告诉我们哪一个表对于每一行都有“未配对”行。在解决方案中,我使用max(source)
(因为我们不应该按“source”分组,因此我们需要在其上使用聚合函数),但它实际上是max()
超过单个值;它就是那个价值。
此解决方案很有效,因为它不使用连接,并且它不使用昂贵的MINUS
操作(或实际上,两个MINUS
操作,并且还读取每个表两次而不是一次,如果分配是从两个表中找到不成对的行,而不只是从一个表中找到。)
select max(source), person_id, start_date, end_date
from ( select 'per_asg' as source, person_id, start_date, end_date from per_asg
union all
select 'xx_per_asg' as source, person_id, start_date, end_date from xx_per_asg
)
group by person_id, start_date, end_date
having count(*) = 1
order by person_id, start_date, end_date -- ORDER BY is optional
;
还有一件事 - 如果您按start_date
进行比较,则必须确保所有日期都是“纯日期”(没有时间组件);也就是说,时间组件应为00:00:00
。是这样的吗?如果不是,则需要调整所有解决方案(并且效率会降低,这会更耗时)。
答案 2 :(得分:0)
如果在示例中看起来,两个表中的行相等,则逐字段,您可以这样做:
select * from xx_per_asg
minus
select * from per_asg
答案 3 :(得分:0)
System.Diagnostics.Process proc = new System.Diagnostics.Process();
string path = System.IO.Directory.GetParent(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)).FullName;
if (Environment.OSVersion.Version.Major >= 6)
{
path = System.IO.Directory.GetParent(path).ToString();
}
proc.StartInfo.WorkingDirectory = path;
proc.StartInfo.FileName = "cmd.exe";
proc.StartInfo.Arguments = "/k git --version";
proc.Start();