在sql

时间:2016-10-22 16:55:11

标签: sql oracle oracle-sqldeveloper

我有两张表per_asgxx_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

但这仍然是整套数据

4 个答案:

答案 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();