2011-03-15 71 views
0

我正在研究一個解析程序,它將兩個文件中的信息解析爲一個 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

回答

2

下面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

相關問題