如何结合两个表行满足一系列条件

问题描述:

我正在研究一个解析程序,它将两个文件中的信息解析为一个 sqlite3表。如何结合两个表行满足一系列条件

可以说该表具有以下值: 文件名,值2,值3,值4

从来没有超过两个表名值, 我想编写一个sql查询以下 条件时将加入两行是真正的

  • 行X:文件名= Y行:文件名
  • 行X:值2 ==排Y:值2
  • 行X:VALUE3 ==排Y:VALUE3
  • 行X:VALUE4 ==排Y:VALUE4

好我的工作的实际程序是更复杂一点,所以也许这将是一个更清晰一点

FILE1.TXT内容

abcd, 1234, efgh 
klmn, 5678, opqr 
stuv, 9abc, wxyz 

FILE2.TXT内容

abcd, 1234, efgh 
klmn, 9ffx, opqr 
stuv, 9abc, wxyz 

所需的输出:

  • FILE1.TXT,ABCD,1234,EFGH FILE2.TXT,ABCD,1234,EFGH
  • file1.txt,klmn,5678,opqr, - , - , - , -
  • - , - , - , - ,FILE2.TXT KLMN,fffx,使用opqr
  • FILE1.TXT,STUV,9ABC,WXYZ,FILE2.TXT,STUV,9ABC,WXYZ

下面x是表名

select a.*, b.* 
from x as a 
inner join x as b 
    on a.filename<b.filename 
    and a.value2 = b.value2 
     and a.value3 = b.value3 
     and a.value4 = b.value4 
union all 
select a.*, b.* 
from x as a 
left join x as b 
    on a.filename!=b.filename 
     and a.value2 = b.value2 
     and a.value3 = b.value3 
     and a.value4 = b.value4 
where b.filename is null 
    and a.filename = (select min(filename) from x) 
union all 
select b.*, a.* 
from x as a 
left join x as b 
    on a.filename!=b.filename 
     and a.value2 = b.value2 
     and a.value3 = b.value3 
     and a.value4 = b.value4 
where b.filename is null 
    and a.filename = (select max(filename) from x) 

有三个部分

  1. 所有值的两个文件之间不匹配。较小的文件名在左侧列出
  2. 其中值不能与右侧相匹配。 min(filename)仅针对不匹配的左侧文件行进行过滤。
  3. 其中值不能与左侧相匹配。 max(filename)仅针对不匹配的右文件行进行过滤。

除非存在可以拼接到查询中的某些行号列,否则没有办法精确地产生输出顺序(某些固有的排序顺序)。

+0

假设我不想一次查看整个列表。我怎样才能缩短列表的范围,使得只有a.value2和b.value2 ='1234'的结果?我找到的解决方案是:创建视图,如果不存在myview as ...然后创建一个select * from myview其中value2 ='1234'通过修改上面的代码是否有更好/更快的方式做到这一点? – Tom 2011-03-16 15:07:01

+0

@Tom太模棱两可了 - 哪个值为2?请注意,如果您创建视图,则必须命名每个列,因为表中的每列有两个被别名两次。无论如何,如果你想要a.value2 = b.value2 = ,只在第一部分放置一个过滤器(在Union all之前)并忽略查询的其余部分 – RichardTheKiwi 2011-03-16 19:02:02